Reflection

Reflection oder Introspektion bedeutet, dass ein Programm seine eigene Struktur kennt und diese, wenn nötig, modifizieren kann. Das Reflection-Modell von java erlaubt es Objekte und Klassen, die zur Laufzeit im Speicher gehalten werden, zu untersuchen und zu modifizieren.

class ClassSpy


package de.snowbits.reflect;

import java.beans.XMLEncoder;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.List;

public class ClassSpy {

	public static void main(String... args) {
		spy(java.util.Date.class);
		System.out.println("---------------------------------------");
		spy(XMLEncoder.class);
		System.out.println("---------------------------------------");
		spy(java.rmi.RMISecurityException.class);
		
		// Class:
		// 	java.util.Date
		// Modifiers:
		// 	public
		// Type Parameters:
		// 	No Type Parameters
		// Implemented Interfaces:
		// 	interface java.io.Serializable
		// 	interface java.lang.Cloneable
		// 	java.lang.Comparable<java.util.Date>
		// Inheritance Path:
		// 	java.lang.Object
		// Annotations:
		// 	No Annotations
		// ---------------------------------------
		// Class:
		// 	java.beans.XMLEncoder
		// Modifiers:
		// 	public
		// Type Parameters:
		// 	No Type Parameters
		// Implemented Interfaces:
		// 	interface java.lang.AutoCloseable
		// Inheritance Path:
		// 	java.beans.Encoder
		// 	java.lang.Object
		// Annotations:
		// 	No Annotations
		// ---------------------------------------
		// Class:
		// 	java.rmi.RMISecurityException
		// Modifiers:
		// 	public
		// Type Parameters:
		// 	No Type Parameters
		// Implemented Interfaces:
		// 	No Implemented Interfaces
		// Inheritance Path:
		// 	java.lang.SecurityException
		// 	java.lang.RuntimeException
		// 	java.lang.Exception
		// 	java.lang.Throwable
		// 	java.lang.Object
		// Annotations:
		// 	@java.lang.Deprecated()		
	}

	@SuppressWarnings("rawtypes")
	private static void spy(Class<?> clazz) {
		debug("Class", clazz.getCanonicalName());
		debug("Modifiers", Modifier.toString(clazz.getModifiers()));

		debug("Type Parameters", null);
		TypeVariable[] typeVariable = clazz.getTypeParameters();
				
		if (typeVariable.length > 0) {
			for (TypeVariable element : typeVariable) {
				debug(element.getName());
			}
		} else {
			debug("No Type Parameters");
		}

		debug("Implemented Interfaces", null);
		Type[] impInterfaces = clazz.getGenericInterfaces();
		if (impInterfaces.length > 0) {
			for (Type element : impInterfaces) {
				debug(element.toString());				
			}
		} else {
			debug("No Implemented Interfaces");
		}

		debug("Inheritance Path", null);
		List<Class> superClass = new ArrayList<Class>();
		debug(clazz, superClass);
		if (superClass.size() != 0) {
			for (Class<?> element : superClass) {
				debug(element.getCanonicalName());
			}
		} else {
			debug("No Super Classes");
		}

		debug("Annotations", null);
		Annotation[] annotation = clazz.getAnnotations();
		if (annotation.length > 0) {
			for (Annotation element : annotation) {
				debug(element.toString());
			}
		} else {
			debug("No Annotations");
		}
	}

	private static void debug(String message) {
		debug(null, message);
	}
	
	private static void debug(String prefix, String message) {
		if (prefix != null && message != null) {
			System.out.println(prefix + ":\n\t" + message);
		} else if (prefix != null && message == null) {
			System.out.println(prefix + ":");			
		} else {
			System.out.println("\t" + message);
		}
	}
	
	@SuppressWarnings("rawtypes")
	private static void debug(Class<?> clazz, List<Class> listClass) {
		Class<?> ancestor = clazz.getSuperclass();
		if (ancestor != null) {
			listClass.add(ancestor);
			debug(ancestor, listClass);
		}
	}
}
	

class ReflectionAB


package de.snowbits.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


public class ReflectionAB {
	
	private static final String METHOD_SAY_HELLO = "sayHello";
	private static final String METHOD_GET_VALUE = "getValue";

	public static void main(String[] args) {
		ReflectionAB reflect = new ReflectionAB();

		try {
			System.out.println("...reflect.a.A: " + 
					reflect.invokeFor(new de.snowbits.reflect.a.A()));
			System.out.println("...reflect.b.B: " + 
					reflect.invokeFor(new de.snowbits.reflect.b.B()));			
			System.out.println("...reflect.a.A: " + 
					reflect.invokeFor(new de.snowbits.reflect.a.A(), "Maxi", 25));
			System.out.println("...reflect.b.B: " + 
					reflect.invokeFor(new de.snowbits.reflect.b.B(), "Max", 27));
			// ...reflect.a.A: I am A
			// ...reflect.b.B: I am B
			// ...reflect.a.A: Hello Maxi 25´er, I am A
			// ...reflect.b.B: Hello Max 27´er, I am B
		} catch (ReflectionException e) {
			e.printStackTrace();
		}
		
	}
	
	public String invokeFor(Object invokeObject) throws ReflectionException {
		try {
			Method method = Class.forName(invokeObject.getClass().getName())
							.getMethod(METHOD_GET_VALUE);
			
			return (String) method.invoke(invokeObject, new Object[] {});
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | 
				NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			throw new ReflectionException(getErrorMessage(invokeObject, METHOD_GET_VALUE), e);
		}
	}	
	
	public String invokeFor(Object invokeObject, String firstname, int age) throws ReflectionException {
		try {
			Method method = Class.forName(invokeObject.getClass().getName())
					       .getMethod(METHOD_SAY_HELLO, java.lang.String.class, java.lang.Integer.class);
			
			return (String) method.invoke(invokeObject, new Object[] {firstname, age});
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | 
				NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			throw new ReflectionException(getErrorMessage(invokeObject, METHOD_SAY_HELLO), e);
		}
	}	
	
	private String getErrorMessage(Object invokeObject, String method) {
		return "Error error at reflecting from "
				+ "[class: " +	invokeObject.getClass().getName() 
				+ "; method: " + method + "]";
	}
	
	@SuppressWarnings("serial")
	public class ReflectionException extends Exception {

		public ReflectionException(String message, Throwable cause) {
			super(message, cause);
		}
	}
}
	

class A


package de.snowbits.reflect.a;

public class A {

	public static final String NAME = "I am A";
	
	public String getValue() {
		return NAME;
	}
	
	public String sayHello(String firstname, Integer age) {
		return "Hello " + firstname + " " + age + "´er, " + NAME;
	}
}
	

class B


package de.snowbits.reflect.b;

public class B {
	
	public static final String NAME = "I am B";
	
	public String getValue() {
		return NAME;
	}
	
	public String sayHello(String firstname, Integer age) {
		return "Hello " + firstname + " " + age + "´er, " + NAME;
	}
}
	

class de.snowbits.reflect.ReflectNotify


package de.snowbits.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class ReflectNotify {

	private static final String METHOD_GET_NOTIFY   = "getNotify";
	private static final String METHOD_GET_PERSON   = "getPerson";
	private static final String METHOD_GET_FULLNAME = "getFullname";
	private static final String METHOD_GET_AGE      = "getAge";
			
	public <N, P> List<de.snowbits.reflect.Person> parseNotifyPersons(Object invokeObject) throws ReflectException {
		List<de.snowbits.reflect.Person> result = new ArrayList<>();
		try {
			N notify = invokeNotify(invokeObject);
			P[] personArray = invokeArrayPerson(notify);
			
			for (P element : personArray) {
				result.add(parsePerson(element));
			}
			
			return result;
		} catch (ReflectException e) {
			throw new ReflectException("Error parsing to list with new persons: " +
					de.snowbits.reflect.Person.class.getName(), e);
		}
	}	
	
	protected de.snowbits.reflect.Person parsePerson(Object invokeObject) throws ReflectException {
		try {
			return new de.snowbits.reflect.Person(invokeFullname(invokeObject), invokeAge(invokeObject));
		} catch (ReflectException e) {
			throw new ReflectException("Error parsing to new person: " +
					de.snowbits.reflect.Person.class.getName(), e);
		}
	}
	
	@SuppressWarnings("unchecked")
	protected <T> T invokeNotify(Object invokeObject) throws ReflectException {
		try {
			Method method = Class.forName(invokeObject.getClass().getName())
							.getMethod(METHOD_GET_NOTIFY);
			
			return (T) method.invoke(invokeObject, new Object[] {});
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | 
				NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			throw new ReflectException(getErrorMessage(invokeObject, METHOD_GET_NOTIFY), e);
		}
	}	
	
	@SuppressWarnings("unchecked")
	protected <T> T[] invokeArrayPerson(Object invokeObject) throws ReflectException {
		try {
			Method method = Class.forName(invokeObject.getClass().getName())
							.getMethod(METHOD_GET_PERSON);
			
			return (T[]) method.invoke(invokeObject, new Object[] {});
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | 
				NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			throw new ReflectException(getErrorMessage(invokeObject, METHOD_GET_PERSON), e);
		}
	}		
	
	protected String invokeFullname(Object invokeObject) throws ReflectException {
		try {
			Method method = Class.forName(invokeObject.getClass().getName())
							.getMethod(METHOD_GET_FULLNAME);
			
			return (String) method.invoke(invokeObject, new Object[] {});
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | 
				NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			throw new ReflectException(getErrorMessage(invokeObject, METHOD_GET_FULLNAME), e);
		}
	}
	
	protected Integer invokeAge(Object invokeObject) throws ReflectException {
		try {
			Method method = Class.forName(invokeObject.getClass().getName())
							.getMethod(METHOD_GET_AGE);
			
			return (Integer) method.invoke(invokeObject, new Object[] {});
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | 
				NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			throw new ReflectException(getErrorMessage(invokeObject, METHOD_GET_AGE), e);
		}
	}
	
	private String getErrorMessage(Object invokeObject, String method) {
		return "Error error at reflecting from "
				+ "[class: " +	invokeObject.getClass().getName() 
				+ "; method: " + method + "]";
	}	
	
	@SuppressWarnings("serial")
	public class ReflectException extends Exception {

		public ReflectException(String message, Throwable cause) {
			super(message, cause);
		}
	}
}
	

class de.snowbits.reflect.ReflectNotifyTest


package de.snowbits.reflect;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.util.List;

import org.junit.Before;
import org.junit.Test;

import de.snowbits.reflect.ReflectNotify.ReflectException;

public class ReflectNotifyTest {

	private static final String FULLNAME_AB_1 ="Max Muster";
	private static final String FULLNAME_AB_2 ="Maxi Muster";
	private static final Integer AGE_AB_1     = 25;
	private static final Integer AGE_AB_2     = 22;

	private static final String FULLNAME_XY_1 ="Hagen Muster";
	private static final String FULLNAME_XY_2 ="Hanne Muster";
	private static final Integer AGE_XY_1     = 33;
	private static final Integer AGE_XY_2     = 30;
	
	private de.snowbits.reflect.ab.Response _responseAB;
	private de.snowbits.reflect.ab.Response.Notify _notifyAB;
	private de.snowbits.reflect.ab.Person[] _personAB;
	
	private de.snowbits.reflect.xy.Response _responseXY;
	private de.snowbits.reflect.xy.Response.Notify _notifyXY;
	private de.snowbits.reflect.xy.Person[] _personXY;

	@Before
	public void setUp() throws Exception {
		_responseAB = null;
		_notifyAB = null;
		_personAB = null;
		_responseXY = null;
		_notifyXY = null;
		_personXY = null;
	}

	@Test
	public void provideNotifyAB() throws ReflectException {
		initAB();
		_notifyAB = testee().invokeNotify(_responseAB);
		assertNotNull(_notifyAB);
		assertTrue(_notifyAB.getPerson().length == 2);
		assertTrue(isPersonAB(_notifyAB.getPerson()));
	}
	
	@Test
	public void providePersonAB() throws ReflectException {
		initAB();
		_notifyAB = testee().invokeNotify(_responseAB);
		_personAB = testee().invokeArrayPerson(_notifyAB);
		assertNotNull(_personAB);
		assertTrue(_personAB.length == 2);
		assertTrue(isPersonAB(_personAB));
	}	

	@Test
	public void provideNotifyXY() throws ReflectException {
		initXY();
		_notifyXY = testee().invokeNotify(_responseXY);
		assertNotNull(_notifyXY);
		assertTrue(_notifyXY.getPerson().length == 2);
		assertTrue(isPersonXY(_notifyXY.getPerson()));
	}
	
	@Test
	public void providePersonXY() throws ReflectException {
		initXY();
		_notifyXY = testee().invokeNotify(_responseXY);
		_personXY = testee().invokeArrayPerson(_notifyXY);
		assertNotNull(_personXY);
		assertTrue(_personXY.length == 2);
		assertTrue(isPersonXY(_personXY));
	}	
	
	@Test
	public void provideFullnameAB() throws ReflectException {
		initAB();
		_notifyAB = testee().invokeNotify(_responseAB);
		_personAB = testee().invokeArrayPerson(_notifyAB);
		
		for (de.snowbits.reflect.ab.Person element : _personAB) {
			String fullname = testee().invokeFullname(element);

			assertNotNull(fullname);
			assertTrue(fullname.equals(FULLNAME_AB_1) || fullname.equals(FULLNAME_AB_2));
		}
	}
	
	@Test
	public void provideAgeAB() throws ReflectException {
		initAB();
		_notifyAB = testee().invokeNotify(_responseAB);
		_personAB = testee().invokeArrayPerson(_notifyAB);
		
		for (de.snowbits.reflect.ab.Person element : _personAB) {
			Integer age = testee().invokeAge(element);
			
			assertNotNull(age);
			assertTrue(age == AGE_AB_1 || age == AGE_AB_2);
		}
	}
		
	@Test
	public void provideFullnameXY() throws ReflectException {
		initXY();
		_notifyXY = testee().invokeNotify(_responseXY);
		_personXY = testee().invokeArrayPerson(_notifyXY);
		
		for (de.snowbits.reflect.xy.Person element : _personXY) {
			String fullname = testee().invokeFullname(element);

			assertNotNull(fullname);
			assertTrue(fullname.equals(FULLNAME_XY_1) || fullname.equals(FULLNAME_XY_2));
		}
	}
	
	@Test
	public void provideAgeXY() throws ReflectException {
		initXY();
		_notifyXY = testee().invokeNotify(_responseXY);
		_personXY = testee().invokeArrayPerson(_notifyXY);
		
		for (de.snowbits.reflect.xy.Person element : _personXY) {
			Integer age = testee().invokeAge(element);
			
			assertNotNull(age);
			assertTrue(age == AGE_XY_1 || age == AGE_XY_2);
		}
	}	
	
	@Test
	public void parsePersonAB() throws ReflectException {
		initAB();
		_notifyAB = testee().invokeNotify(_responseAB);
		_personAB = testee().invokeArrayPerson(_notifyAB);
		de.snowbits.reflect.Person person = testee().parsePerson(_personAB[0]);
		assertNotNull(person);
		assertTrue(person.getFullname().equals(FULLNAME_AB_1) || 
				   person.getFullname().equals(FULLNAME_AB_2));
		assertTrue(person.getAge() == AGE_AB_1 || person.getAge() == AGE_AB_2);
	}	
	
	@Test
	public void parsePersonXY() throws ReflectException {
		initXY();
		_notifyXY = testee().invokeNotify(_responseXY);
		_personXY = testee().invokeArrayPerson(_notifyXY);
		de.snowbits.reflect.Person person = testee().parsePerson(_personXY[0]);
		assertNotNull(person);
		assertTrue(person.getFullname().equals(FULLNAME_XY_1) || 
				   person.getFullname().equals(FULLNAME_XY_2));
		assertTrue(person.getAge() == AGE_XY_1 || person.getAge() == AGE_XY_2);
	}	
	
	@Test
	public void parseNotifyPersonsAB() throws ReflectException {
		initAB();
		List<de.snowbits.reflect.Person> persons = testee().parseNotifyPersons(_responseAB);
		assertNotNull(persons);
		assertTrue(persons.size() == 2);
		assertTrue(isPersonAB(persons));
	}		
	
	@Test
	public void parseNotifyPersonsXY() throws ReflectException {
		initXY();
		List<de.snowbits.reflect.Person> persons = testee().parseNotifyPersons(_responseXY);
		assertNotNull(persons);
		assertTrue(persons.size() == 2);
		assertTrue(isPersonXY(persons));
	}		
		
	private boolean isPersonAB(List<de.snowbits.reflect.Person> result) {
		int count = 0;
		
		for (de.snowbits.reflect.Person element : result) {
			if ((element.getFullname().equals(FULLNAME_AB_1) ||
				element.getFullname().equals(FULLNAME_AB_2)) &&
				(element.getAge() == AGE_AB_1 || element.getAge() == AGE_AB_2)) {
				count++;
			}
		}
		
		return count == 2;
	}
	
	private boolean isPersonXY(List<de.snowbits.reflect.Person> result) {
		int count = 0;
		
		for (de.snowbits.reflect.Person element : result) {
			if ((element.getFullname().equals(FULLNAME_XY_1) ||
				element.getFullname().equals(FULLNAME_XY_2)) &&
				(element.getAge() == AGE_XY_1 || element.getAge() == AGE_XY_2)) {
				count++;
			}
		}
		
		return count == 2;
	}	
	
	private boolean isPersonAB(de.snowbits.reflect.ab.Person[] result) {
		int count = 0;
		
		for (de.snowbits.reflect.ab.Person element : result) {
			if ((element.getFullname().equals(FULLNAME_AB_1) ||
				element.getFullname().equals(FULLNAME_AB_2)) &&
				(element.getAge() == AGE_AB_1 || element.getAge() == AGE_AB_2)) {
				count++;
			}
		}
		
		return count == 2;
	}

	private boolean isPersonXY(de.snowbits.reflect.xy.Person[] result) {
		int count = 0;
		
		for (de.snowbits.reflect.xy.Person element : result) {
			if ((element.getFullname().equals(FULLNAME_XY_1) ||
				element.getFullname().equals(FULLNAME_XY_2)) &&
				(element.getAge() == AGE_XY_1 || element.getAge() == AGE_XY_2)) {
				count++;
			}
		}
		
		return count == 2;
	}	
	
	private void initAB() {
		_responseAB = new de.snowbits.reflect.ab.Response();
		de.snowbits.reflect.ab.Response.Notify notify = _responseAB.new Notify();
		de.snowbits.reflect.ab.Person[] person = new de.snowbits.reflect.ab.Person[2];
		person[0] = new de.snowbits.reflect.ab.Person(FULLNAME_AB_1, AGE_AB_1);
		person[1] = new de.snowbits.reflect.ab.Person(FULLNAME_AB_2, AGE_AB_2);
		notify.setPerson(person);
		_responseAB.setNotify(notify);
	}

	private void initXY() {
		_responseXY = new de.snowbits.reflect.xy.Response();
		de.snowbits.reflect.xy.Response.Notify notify = _responseXY.new Notify();
		de.snowbits.reflect.xy.Person[] person = new de.snowbits.reflect.xy.Person[2];
		person[0] = new de.snowbits.reflect.xy.Person(FULLNAME_XY_1, AGE_XY_1);
		person[1] = new de.snowbits.reflect.xy.Person(FULLNAME_XY_2, AGE_XY_2);
		notify.setPerson(person);
		_responseXY.setNotify(notify);
	}	
	
	private ReflectNotify testee() {
		return new ReflectNotify();
	}
}
	

class de.snowbits.reflect.Person


package de.snowbits.reflect;

public class Person {
	private String fullname;
	private Integer age;

	public Person(String fullname, Integer age) {
		this.fullname = fullname;
		this.age = age;
	}

	public String getFullname() {
		return fullname;
	}

	public void setFullname(String fullname) {
		this.fullname = fullname;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}
	

class de.snowbits.reflect.ab.Response


package de.snowbits.reflect.ab;

public class Response {

	private de.snowbits.reflect.ab.Response.Notify notify;

	public de.snowbits.reflect.ab.Response.Notify getNotify() {
		return notify;
	}

	public void setNotify(de.snowbits.reflect.ab.Response.Notify notify) {
		this.notify = notify;
	}

	public class Notify {
		private de.snowbits.reflect.ab.Person[] person;

		public Person[] getPerson() {
			return person;
		}

		public void setPerson(de.snowbits.reflect.ab.Person[] person) {
			this.person = person;
		}
	}
	
}
	

class de.snowbits.reflect.ab.Person


package de.snowbits.reflect.ab;

public class Person {
	private String fullname;
	private Integer age;

	public Person(String fullname, Integer age) {
		this.fullname = fullname;
		this.age = age;
	}

	public String getFullname() {
		return fullname;
	}

	public void setFullname(String fullname) {
		this.fullname = fullname;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}
	

class de.snowbits.reflect.xy.Response


package de.snowbits.reflect.xy;

public class Response {

	private de.snowbits.reflect.xy.Response.Notify notify;

	public de.snowbits.reflect.xy.Response.Notify getNotify() {
		return notify;
	}

	public void setNotify(de.snowbits.reflect.xy.Response.Notify notify) {
		this.notify = notify;
	}

	public class Notify {
		private de.snowbits.reflect.xy.Person[] person;

		public Person[] getPerson() {
			return person;
		}

		public void setPerson(de.snowbits.reflect.xy.Person[] person) {
			this.person = person;
		}
	}
	
}
	

class de.snowbits.reflect.xy.Person


package de.snowbits.reflect.xy;

public class Person {
	private String fullname;
	private Integer age;

	public Person(String fullname, Integer age) {
		this.fullname = fullname;
		this.age = age;
	}

	public String getFullname() {
		return fullname;
	}

	public void setFullname(String fullname) {
		this.fullname = fullname;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}
	

Top


Example
Sitemap Kontakt Impressum