1绕过编译阶段为集合添加数据
反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,此时是可以为集合存入其他任意类型的元素的
泛型只是编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进行运行阶段的时候,其真实类型都是ArrayListl了,泛型相当于被擦除了
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) throws Exception{
//定义两个不同泛型的集合,观察他们的Class对象
ArrayList<Integer> list1=new ArrayList<>();
ArrayList<String> list2=new ArrayList<>();
System.out.println(list1.getClass()); //class java.util.ArrayList
System.out.println(list2.getClass()); //class java.util.ArrayList
System.out.println(list1.getClass()==list2.getClass()); //true
//泛型不同,但是Class文件是一样
list1.add(22);
//list1.add("张三");//报错
//通过反射越过泛型
Class c=list1.getClass();
Method myAdd= c.getMethod("add",Object.class);
myAdd.invoke(list1, "张三");
System.out.println(list1);//输出 [22, 张三]
}
}
不用反射就这样写也可以突破泛型约束
ArrayList< Integer> list01=new ArrayList<>();
List list02=list01;
list02.add("张三");
System.out.println(list01);
2:反射做通用框架
需求:给你任意一个对象,在不清楚对象字段的情况下,可以把对象的字段名和对应值存储到文件中去
分析:
定义一个方法,可以接收任意类型的对象
每次受到一个对象后,需要解析这个对象的全部成员变量名称
这个对象可能是任意的,那么怎么样可以知道这个对象的全部成员变量名称呢?
使用反射获取对象的Class类对象,然后获取全部对象变量信息。
遍历变量信息,然后提取成本成员变量在对象的具体值
存入成员变量名称和值到对应的文件中去即可
创建学生类
package 反射通用框架;
public class Student {
private String name;
private int age;
private String hobby; //爱好
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* @return the hobby
*/
public String getHobby() {
return hobby;
}
/**
* @param hobby the hobby to set
*/
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Student(String name, int age, String hobby) {
super();
this.name = name;
this.age = age;
this.hobby = hobby;
}
public Student() {
super();
}
}
创建老师类
package 反射通用框架;
public class Teacher {
private String name;
private int age;
private double salary;//薪水
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* @return the salary
*/
public double getSalary() {
return salary;
}
/**
* @param salary the salary to set
*/
public void setSalary(double salary) {
this.salary = salary;
}
public Teacher(String name, int age, double salary) {
super();
this.name = name;
this.age = age;
this.salary = salary;
}
public Teacher() {
super();
}
}
创建个工具类写个方法
package 反射通用框架;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.spec.PSSParameterSpec;
public class MyTool {
/**
* 输出对象信息到文件
*/
public static void toFile(Object obj) {
try(PrintStream ps=new PrintStream(new FileOutputStream("D:/aaaaa.txt",true))){
//获取对应的类对象
Class c=obj.getClass();
//获取对应类的全部方法
ps.println("------------"+c.getSimpleName()+"------------"); //获取拿到的类名
Field[] arr=c.getDeclaredFields();
//遍历获取到的全部方法
for (Field field : arr) {
String name=field.getName();//获取成员变量的名称
field.setAccessible(true);//暴力反射
String value=field.get(obj)+"";// 获取值
ps.println(name+"------>"+value);
}
System.out.println("输出到文件成功");
} catch (Exception e) {
e.printStackTrace();
}
}
}
主函数
package 反射通用框架;
public class Test {
public static void main(String[] args) {
Student s1=new Student("张三",20,"跑步");
MyTool.toFile(s1);
Teacher t1=new Teacher("李老师",30,3000);
MyTool.toFile(t1);
}
}
最后也是成功的打印到了文件