Java的反射机制与泛型擦除

实现方式
  反编译:.class–>.java
  通过反射机制访问java对象的属性,方法,构造方法等
涉及类
  java.lang.Class;
  java.lang.reflect.Constructor;
  java.lang.reflect.Field;
  java.lang.reflect.Method;
  java.lang.reflect.Modifier;
Field
  Java反射中Field用于获取某个类的属性或该属性的属性值

反射获取类的三种方法

Class c1 = Class.forName("Book");
Class c2 = Book.class; // Java中每个类型都有class属性
Book book= new Book(); // java语言中任何一个java对象都有getClass 方法 
Class c3 = book.getClass(); // c3是运行时类 (book的运行时类是Book)

创建对象
获取类以后我们来创建它的对象,利用newInstance:

Class c =Class.forName("Book");  

// 创建此Class 对象所表示的类的一个新实例  
Object o = c.newInstance(); // 调用Book的无参数构造方法. 

获取所有属性

Class c = Class.forName("java.lang.Integer"); // 获取整个类  
Field[] fs = c.getDeclaredFields();  // 获取所有的属性
StringBuffer sb = new StringBuffer();  // 定义可变长的字符串,用来存储属性

sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");  // 通过追加的方法,将public定义里边的每一个属性拼接到此字符串中
for(Field field:fs){  
    sb.append("\t"); // Tab  
    sb.append(Modifier.toString(field.getModifiers())+" "); // 获得属性的修饰符,例如public,static等  
    sb.append(field.getType().getSimpleName() + " ");// 属性的类型的名字  
    sb.append(field.getName()+";\n"); // 属性名字+回车换行  
}  
sb.append("}");  
System.out.println(sb); 

获取指定属性

Class c = Class.forName("User"); // 获取类  
Field idF = c.getDeclaredField("id"); // 获取id属性  
Object o = c.newInstance(); // 实例化这个类赋给o 
idF.setAccessible(true); // 打破封装 :使用反射机制可以打破封装性,导致了对象的属性不安全。
idF.set(o, "110"); // set,给o对象的id属性赋值"110" 
System.out.println(idF.get(o)); // get 

获取方法和构造方法

使用反射进行泛型擦除

package com.test;
 
import java.lang.reflect.Method;
import java.util.ArrayList;
 
public class test_fanxing {
    /**
     * * ArrayList<Integer>的一个对象,在这个集合中添加一个字符串数据,如何实现呢?
     * 泛型只在编译期有效,在运行期会被擦除掉*/
    public static void main(String[] args) throws Exception{
        ArrayList<Integer> list=new ArrayList<>();
        list.add(123);
        list.add(321);
        //list.add( "www"); 将会报错  为了解决这个问题,我们对其add方法进行反射,讲字符串添加进去
        //因为不在编译期 所以泛型无效
        Class clazz=Class.forName("java.util.ArrayList");
        Method m=clazz.getMethod("add",Object.class); //API add(E e) 参数Object
        m.invoke(list,"www");
        System.out.println(list);  //[123, 321, www] 成功反射进来字符串
 
    }
}

猜你喜欢

转载自www.cnblogs.com/liuqing576598117/p/10384142.html