java 反射

java 反射

1 获取class

  • 知道一个类,直接获取 Class 对象
    Class class1 = ReflexBean.class;
  • 如果已经得到了某个对象,可以通过这个对象获取 Class 对象
    ReflexBean bean = new ReflexBean();
    Class<?> class3 = bean.getClass();
  • 如果你在编译期获取不到目标类型,但是你知道它的完整类路径,那么你可以通过如下的形式来获取 Class 对象
    Class<?> class2 = Class.forName("cn.zs.reflex.ReflexBean");

2. 获取构造方法

2.1 获取所有的构造方法

`Constructor[] constructors = class1.getConstructors(); // 获取的构造方法按照在类中定义的顺序`

2.2 获取代参数的构造方法

`Constructor constructor = class1.getConstructor(Integer.class);`

2.3 调用构造方法

`ReflexBean newInstance = (ReflexBean) constructors[0].newInstance(5);`

3. 获取字段

3.1 获取public 字段

`Field[] fields = class1.getFields();
    for (int i = 0; i < fields.length; i++) {
        System.out.println(fields[i].getName());  //获取字段的名称
        System.out.println(fields[i].get(bean));  //获取字段的值,bean为该类的实例
    }`

3.2 获取所有的字段

`Field[] fields2 = class1.getDeclaredFields();
    for (int i = 0; i < fields2.length; i++) {
        fields2[i].setAccessible(true);  //要设置私有字段的访问权限
        System.out.println(fields2[i].getName());
        System.out.println(fields2[i].get(bean));
    }`

3.3 设置字段的值

4. 获取方法

4.1 获取方法的形式参数

`Method[] methods = class1.getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
        methods[i].setAccessible(true);
        System.out.println(methods[i].getName());  //获取方法的名称
        System.out.println(methods[i].getGenericReturnType().toString()); //获取返回值的类型
    Class<?>[] parameterTypes = methods[i].getParameterTypes(); // 获取方法形式参数的类型 注意与getTypeParameters()的区别
        //Type[] genericParameterTypes = methods[i].getGenericParameterTypes(); 也可以获取方法形式参数的类型
        System.out.println(parameterTypes.length);
        for (int j = 0; j < parameterTypes.length; j++) {
            System.out.println(parameterTypes[j].toString());
        }
        System.out.println("---------------------");
    }`

4.2 获取形式参数的名称

因为在Java中并没有提供相应的API 来获取参数列表名称,因此当有这方面的需求的时候可以使用javassist-3.9.0.GA.jar来获取

要获取的方法为
private Long testMethod3(String str, Integer i) {
return 2L;
}

4.3 执行方法

`class3.getMethod("testMethod2", Integer.class,Double.class).invoke( bean, 1,2.0);`

对应类中的方法是
public void testMethod2(Integer i,Double d) {
System.out.println("执行方法"+ "_"+i+"_"+d);
}

获取的代码为

`public class Test2 {
public static void main(String[] args) throws NotFoundException {
    ClassPool classPool = ClassPool.getDefault();

    CtClass ctClass = classPool.get(ReflexBean.class.getName());

    CtMethod declaredMethod = ctClass.getDeclaredMethod("testMethod3");

    MethodInfo methodInfo = declaredMethod.getMethodInfo();

    CodeAttribute codeAttribute = methodInfo.getCodeAttribute();

    LocalVariableAttribute attribute = (LocalVariableAttribute) codeAttribute
            .getAttribute(LocalVariableAttribute.tag);
    //如果执行的是非实例方法(非static方法),局部变量表的第0为索引的Slot默认是传递放方法所属对象实例的引用即this
    int pos = Modifier.isStatic(declaredMethod.getModifiers()) ? 0 : 1; 
    for (int i = 0; i < declaredMethod.getParameterTypes().length; i++) {
        System.out.println(attribute.variableName(i+pos));
    }
}

}

5. 获取注解

5.1 获取字段的注解

`Field field = class3.getDeclaredField("age");
    //field.setAccessible(true);
    TestAnnaction1 annotation = field.getAnnotation(TestAnnaction1.class);
    System.out.println(annotation.value())`

5.2 批量获得注解

`Field field = class3.getDeclaredField("age");
    Annotation[] annotations = field.getAnnotations();
    for (int i = 0; i < annotations.length; i++) {
        //System.out.println(annotations[i].toString()); //获取注解的类型
        System.out.println(annotations[i].annotationType().getCanonicalName());  //获取注解的类型
    }`

5.3 获取特定的注解

`TestAnnaction3 annotation = (TestAnnaction3)class1.getAnnotation(TestAnnaction3.class);
    System.out.println(annotation.id());

对应的注解类型
@Retention(RetentionPolicy.RUNTIME) //类型虚设置为RUNTIME
@Target(ElementType.TYPE)
public @interface TestAnnaction3 {
int id();
}

6 获取实现的接口和父类

6.1获取父类

`        Class superclass = class1.getSuperclass();  //获取父类
    System.out.println(superclass.getCanonicalName());`

6.2 获取实现的接口

`Class[] interfaces = class1.getInterfaces();  // 获取实现的接口
    for (int j = 0; j < interfaces.length; j++) {
        System.out.println(interfaces[j].getCanonicalName());
    }`

7 获取泛型

7.1 获取继承类的泛型

`public void get() {
    Type genericSuperclass = this.getClass().getGenericSuperclass();
    System.out.println("getGenericSuperclass === " + genericSuperclass);
    System.out.println(" class 泛型");
    if (ParameterizedType.class.isAssignableFrom(genericSuperclass
            .getClass())) {
        for (Type type : ((ParameterizedType) genericSuperclass)
                .getActualTypeArguments()) {
            System.out.println(type.toString());
        }
    }`

7.2 获取接口的泛型

`public class TestInfaceImpl implements TestInterface<Integer> {
public void get() {
    Type[] genericInterfaces = this.getClass().getGenericInterfaces();

    for (int i = 0; i < genericInterfaces.length; i++) {
        Type inter = genericInterfaces[i];
        if (ParameterizedType.class.isAssignableFrom(inter
                .getClass())) {
            for (Type type : ((ParameterizedType) inter)
                    .getActualTypeArguments()) {
                System.out.println(type.toString());
            }
        }
    }

}

}
`

7.3 获取List 和 Map的泛型

`public class TestBeanExtends extends TestBean<String> {
List<String> lists;
Map<String, Integer> maps;

public void getList() throws NoSuchFieldException, SecurityException {
    Field declaredField = this.getClass().getDeclaredField("lists");
    Type genericType = declaredField.getGenericType();
    System.out.println("list 泛型");
    if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
        for (Type type : ((ParameterizedType) genericType)
                .getActualTypeArguments()) {
            System.out.println(type.toString());
        }
    }
}

public void getMap() throws NoSuchFieldException, SecurityException {
    Field declaredField = this.getClass().getDeclaredField("maps");
    Type genericType = declaredField.getGenericType();
    System.out.println("map 的泛型");
    if (ParameterizedType.class.isAssignableFrom(genericType.getClass())) {
        for (Type type : ((ParameterizedType) genericType)
                .getActualTypeArguments()) {
            System.out.println(type.toString());
        }
    }
}

`

8 参考文献

http://blog.csdn.net/c379936197/article/details/39432745

http://it.deepinmind.com/java/2014/04/15/constructormethod-parameters-metadata-available-via-reflection-in-jdk-8.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值