Reflexão em Java Programação Orientada por Objetos (POO) Centro de Cálculo Instituto Superior de Engenharia de Lisboa Pedro Alexandre Pereira ([email protected]) Reflexão Reflexão é capacidade de um programa em Java … – se “ver” a si próprio – instanciar partes de si próprio É possível devido à meta-informação – java.lang.Class – java.lang.reflect.Field – java.lang.reflect.Method – java.lang.reflect.Constructor ... A reflexão não permite: – Alterar a estruturalmente uma classe – Modificar código de métodos CCISEL, 2015 Programação Orientada por Objetos 2 Obter o objeto Class • Cada objeto da classe Class representa um tipo • Só existe um objeto para cada tipo, criado no carregamento do tipo. Sabendo o tipo: java.lang.Class class é um campo estático de qualquer classe Class cls = List.class; System.out.println(cls.isInterface()); Dado uma referência para qualquer objeto: Object obj = ... pubic class Object { public final Class getClass() … ... } Class cls = obj.getClass(); System.out.println(cls.getName()); Dado o nome do tipo: String className = ... forName é um método estático da classe Class Class cls = Class.forName(className); System.out.println(cls.getSuperclass().getName()); CCISEL, 2015 Programação Orientada por Objetos 3 Classes mais usadas na reflexão CCISEL, 2015 Programação Orientada por Objetos 4 Obter construtores de uma classe private static void printConstructors(Object obj) { Class<?> cls = obj.getClass(); for (Constructor ctr : cls.getConstructors()) System.out.println(ctr); } Boxing para Integer printConstructors(10); public java.lang.Integer(int) public java.lang.Integer(java.lang.String) throws java.lang.NumberFormatException printConstructors("ISEL"); public public public public public public public public public public public public ... CCISEL, 2015 java.lang.String(byte[],int,int) java.lang.String(byte[],java.nio.charset.Charset) java.lang.String(byte[],int,int,java.nio.charset.Charset) java.lang.String(java.lang.StringBuffer) java.lang.String(byte[]) java.lang.String(int[],int,int) java.lang.String() java.lang.String(char[]) java.lang.String(java.lang.String) java.lang.String(char[],int,int) java.lang.String(byte[],int) java.lang.String(byte[],int,int,int) Programação Orientada por Objetos 5 Chamar método com determinado nome static Object callMethodInt(Object obj, String name, int param) { try { for(Method m : obj.getClass().getDeclaredMethods()) if (name.equals(m.getName()) && m.getParameterCount()==1) { Class<?> t = m.getParameterTypes()[0]; if (t==int.class || t==Integer.class || t==Object.class) return m.invoke(obj,param); } } catch (InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } return null; } System.out.println(callMethodInt("ISEL", "charAt", 1)); S Map<Integer,String> m = ... m.put(10,"Dez"); System.out.println(callMethodInt(m, "get", 10)); Dez CCISEL, 2015 Programação Orientada por Objetos 6 Criar objetos descritos textualmente static Object[] createObjectsFromFile(String fileName) { Object[] objs = null; try (Scanner in = new Scanner(new FileInputStream(fileName)) ) { objs = new Object[in.nextInt()]; for (int i = 0; i < objs.length; i++) objs[i] = Class.forName(in.next()) .getConstructor(new Class[]{String.class}) .newInstance(in.next()); } catch ( ClassNotFoundException | FileNotFoundException | InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) { e.printStackTrace(); public class A { } 4 private String name; return objs; java.lang.String xpto public A(String txt) { } A abc name = txt; java.lang.Integer 27 } A ISEL public String toString() { return name; Object[] array = createObjectsFromFile("objects.txt"); } for (Object o : array) } System.out.println(o.getClass().getName()+":"+o); java.lang.String:xpto A:abc java.lang.Integer:27 A:ISEL CCISEL, 2015 Programação Orientada por Objetos 7