云乐国鑫

JAVA反射

反射

Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。

功能

  • 在运行时构造任意一个类的对象。
  • 在运行时获取任意一个类所具有的成员变量和方法。
  • 在运行时调用任意一个对象的方法(属性)。
  • 生成动态代理。

实现(java.lang.reflect)

  • Class 类:反射的核心类,可以获取类的属性,方法等信息。
  • Field 类:Java.lang.reflect 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值。
  • Method 类:Java.lang.reflect 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
  • Constructor 类:java.lang.reflect 包中的类,表示类的构造方法。
// 创建一个类
public static class MyObject {
	// protected 无法获取
    MyObject() {
    }
	// public 可以获取
    public MyObject(String name) {
    }
	// private 无法获取
    private MyObject(int age) {
    }
}
// 获取Class对象
Class<MyObject> clazz = MyObject.class;
// 1. 获取所有的Public构造器
Constructor<?>[] constructors = clazz.getConstructors();
// Constructors=[public tiny.wong.ConstructorTest$MyObject(java.lang.String)]
System.out.println("Constructors="+ Arrays.toString(constructors));
// 2. 获取指定参数类型的构造器
Constructor constructor = clazz.getConstructor(new Class[]{String.class});
Constructor constructor = constructors[0];
// 参数个数
int parameterCount = constructor.getParameterCount();
// 参数类型
Class[] parameterTypes = constructor.getParameterTypes();
// 访问修饰符
int modifiers = constructor.getModifiers();
// 获取方法注解
Annotation[] annotations = constructor.getAnnotations();
Annotation annotation = constructor.getAnnotation(null);
// 获取参数注解
constructor.getParameterAnnotations();
// 创建对象
try {
	// newInstance 的参数是可变参数列表.
    MyObject name = (MyObject) constructor.newInstance("name");
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}
Son son = new Son();
Class clazz = Son.class;
// 1.1 获取所有的Public方法(包含父类)
Field[] fields = clazz.getFields();
// 1.2 获取指定的名称的Public Field
try {
    Field theField = clazz.getField("fieldName");
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}
// 1.3 获取当前类的所有成员变量(不含父类)
Field[] declaredFields = clazz.getDeclaredFields();
// 1.4 获取当前类的指定成员变量(不含父类)
try {
    Field theField1 = clazz.getDeclaredField("fieldName");
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}
// 2. Filed 的相关操作
Field field = fields[0];
// 2.1 变量名字
String filedName = field.getName();
// 2.2 变量类型
Class<?> type = field.getType();
try {
    // 2.3 变量值
    Object o = field.get(son);
    // 2.4 设置成员变量的值
    field.set(son, null);
} catch (IllegalAccessException e) {
    e.printStackTrace();
}
// 2.5 变量注解
Annotation[] annotations = field.getAnnotations();
Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
Annotation annotation = field.getAnnotation(null);
// 2.6 变量的访问修饰符
int modifiers = field.getModifiers();
Son son = new Son();
Class clazz = Son.class;
// 获取私有属性
try {
    Field name = clazz.getDeclaredField("name");
    // 调用 setAccessible()方法会关闭指定类 Field 实例的反射访问检查
    // 如果不进行设置, 可能会访问不到.
    name.setAccessible(true);
    // 获取属性值
    Object value = name.get(son);
    // 设置属性值
    name.set(son, null);
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}
Son son = new Son();
Class clazz = Son.class;
// 1. 获取Method对象.
// 1.1 获取所有的Public方法(含父类)
Method[] methods = clazz.getMethods();
// 1.2 获取当前类所有的方法(不含父类)
Method[] declaredMethods = clazz.getDeclaredMethods();
// 1.3 获取指定方法.规则和上面一样.
try {
    Method method = clazz.getMethod("method", null);
    Method method1 = clazz.getDeclaredMethod("method", null);
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}
Method method = methods[0];
// 2. 方法名
String name = method.getName();
// 3. 方法返回值类型
Class<?> returnType = method.getReturnType();
// 4. 方法参数类型
Class<?>[] parameterTypes = method.getParameterTypes();
// 5. 方法调用
try {
    method.invoke(son, null);
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}
// 6. 方法注解
Annotation[] annotations = method.getAnnotations();
Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
method.getDeclaredAnnotation(null);
Son son = new Son();
Class clazz = Son.class;
try {
    // 获取私有方法, 只能通过getDeclaredMethod,不能使用getMethod因为后者只能获取到Public修饰的方法.
    Method test = clazz.getDeclaredMethod("test", new Class[]{String.class});
    // 设置访问屏蔽反射访问检查
    test.setAccessible(true);
    // 调用方法
    test.invoke(son, "test");
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}
public class GetterAndSetterDemo {
    public static void testGetterAndSetter() {
        Son son = new Son();
        Class clazz = Son.class;
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println("MName=" + method + " is Setter=" + isSetter(method));
            System.out.println("MName=" + method + " is Getter=" + isGetter(method));
        }
    }
    public static boolean isGetter(Method method){
        if (!method.getName().startsWith("get")) {
            return false;
        }
        if (method.getParameterTypes().length != 0) {
            return false;
        }
        if (void.class.equals(method.getReturnType())) {
            return false;
        }
        return true;
    }
    public static boolean isSetter(Method method) {
        if (!method.getName().startsWith("set")) {
            return false;
        }
        if (method.getParameterTypes().length != 1) {
            return false;
        }
        if (!void.class.equals(method.getReturnType())) {
            return false;
        }
        return true;
    }
}
Son son = new Son();
Class clazz = Son.class;
// 1. 方法注解
Method[] methods = clazz.getMethods();
Annotation[] annotations = methods[0].getAnnotations();
for (Annotation anno : annotations) {
    if (anno instanceof Deprecated) {
        System.out.println("Method Deprecated");
    }
}
// 2. 变量注解
Field[] fields = clazz.getFields();
Annotation[] annotations1 = fields[0].getAnnotations();
for (Annotation anno : annotations1) {
    if (anno instanceof Deprecated) {
        System.out.println("Method Deprecated");
    }
}
public static void testArray() {
    // Java 反射机制通过 java.lang.reflect.Array 这个类来处理数组
    // 1. 创建一个数组
    int[] intArray = (int[]) Array.newInstance(int.class, 4);
    // 2. 设置数组元素值
    Array.set(intArray, 0, 0);
    Array.set(intArray, 1, 1);
    // 3. 获取元素值
    Array.get(intArray, 0);
    Array.get(intArray, 1);
    // 4. 获取数组的成员类型
    Class aClass = intArray.getClass();
    Class componentType = aClass.getComponentType();
    // 获取数组的Class
    Class clazz1 = String[].class;
    try {
        // 在JVM中I代表int, [ 表示是数组.比如 "[Ljava.lang.String;"
        Class clazz2 = Class.forName("[I");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    // 注意基本数据类型的Class不能直接用I或者int配合Class.forName来获取
}
posted @ 2015-05-09 14:14  国鑫  阅读(159)  评论(0)    收藏  举报
版权所有@snzigod