package jef.tools.reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
/**
* JDK的反射机制有一个遗憾,<BR>我们看下面这个场景
* <pre><code>
* public abstract class A<K>{
* public K method1();
* }
* public class B extends A<String>{
* }
* </code></pre></P>
* 当我们通过以下代码尝试获得方法的返回参数类型时:<BR>
* <P><code>
* Method method=B.class.getMethod("method1");//看上去这个method是从B中得到的<BR>
* method.getReturnType(); //期望得到String.class,实际得到Object.class<BR>
* method.getGenericReturnType();//即使用这个方法也一样,不会得到String.class<BR>
* </code></P>
* <BR>
* 上述问题其实说明了,任何一个泛型计算都需要有一个上下文。只有提供A<String>这个上下文,才能正确得到A当中的方法method1的返回类型。
* 而Java反射接口的设计中,这个上下文被丢弃了。从一个class实例中得到Method对象中只有一个DeclearingClass,当泛型的子类继承父类时这个DeclearingClass并非之前的那个class实例,
* 而之前的class实例实际上不存在于Method当中。<BR>
* Field也有类似的问题。<BR>
* <BR>
* 即任意一个Field实例中,由于丢失了实际所在的class(子类)信息,只保留了DeclearingClass(父类),
* 从而也就丢失了泛型的提供者, 因此永远不可能计算出泛型的最小边界。
* 在泛型的场合下计算边界,三个泛型提供者Class/Methid/Field缺一不可。
* 为了弥补JDK的这个缺陷,提供了{@link FieldEx},{@link MethodEx}和{@link ClassEx}类提供method对象的包装。
* @see ClassEx
* @see MethodEx
*
*/
public class FieldEx {
private java.lang.reflect.Field field;
ClassEx instanceClass;
private Type genericType;
private FieldAccessor accessor;
public FieldEx(java.lang.reflect.Field method){
this(method,(Class<?>)null);
}
FieldEx(Field field, ClassEx clz) {
this.field=field;
this.instanceClass=clz;
this.genericType=clz.getFieldGenericType(field);
accessor=FieldAccessor.generateAccessor(field);
}
public FieldEx(Field field, Class<?> clz) {
this.field=field;
this.instanceClass=new ClassEx(clz);
}
public java.lang.reflect.Field getJavaField() {
return field;
}
public Class<?> getInstanceClass() {
return instanceClass.getWrappered();
}
public String getName() {
return field.getName();
}
public Object get(Object obj) {
return accessor.getObject(obj);
}
@Override
public int hashCode() {
return field.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof FieldEx){
return this.field.equals(((FieldEx) obj).field);
}
return field.equals(obj);
}
public <T extends Annotation> T getAnnotation(Class<T> class1) {
return field.getAnnotation(class1);
}
public Class<?> getType() {
return field.getType();
}
public Type getGenericType(){
return genericType;
}
public void set(Object bean, Object value){
accessor.set(bean, value);
}
/**
* 得到 field所在的定义类
* @return
*/
public Class<?> getDeclaringClass() {
return field.getDeclaringClass();
}
/**
* 得到field在定义类中的类型边界
* @return
*/
public Class<?> getDeclaringType() {
return field.getType();
}
@Override
public String toString() {
int mod = field.getModifiers();
StringBuilder sb=new StringBuilder(80);
if(mod!=0)sb.append(Modifier.toString(mod)).append(' ');
Type type=this.getGenericType();
sb.append((type instanceof Class)?((Class<?>)type).getName():type.toString()).append(' ');
sb.append(getInstanceClass().getName()).append('.');
sb.append(getName());
return sb.toString();
}
public int getModifiers() {
return field.getModifiers();
}
public void setAccessible(boolean flag) {
field.setAccessible(flag);
}
public FieldAccessor getAccessor(){
return accessor;
}
public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) {
return field.isAnnotationPresent(annotationType);
}
public Annotation[] getAnnotations() {
return field.getAnnotations();
}
}