反射就是对(类)(类的字节码文件)的解剖,用来自己搭建框架 ssh ssm 搭建框架的基础
类:属性 方法 构造方法
java原文件 javac编译 生成class(字节码文件,真正在内存中运行的东西)
用反射解剖类
第一步首先要得到类的字节码文件(得到方式三种) :
1. 类名.class 返回class类型 (万物皆对象,字节码文件也是对象)
Class clazz = Person.class;
syso(clazz); // 可以看一下字节码
2. 对象.getClass();
Person p=new Person(); //创建一个对象
Class clazz=p.getClass(); //在一个.java 文件中 这个clazz 和上面那个clazz相等
//不管怎么得到 ,都是那一个
3.(常用)class.forName(类名);//传全路径类名 包名+类名
Eclipse中快速复制类的全路径名字:
选中 右键 选择” Copy Qualified Name“ Ctrl+v粘贴就ok
Class clazz=Class.forName("com.huida.reflect.Person");
为什么用第三种:可扩展性强
(定义一个方法,只要用户把全路径传进来就可以得到字节码文件)
第二步要解剖类中的属性(字段 Field):(API中 用class类中的方法)
例子:解剖Person中的属性
Class Person{
//属性
String name;//默认的是default
//public String name;
//private int age;
//protected boolean sex;
//构造方法(三个构造方法)
public Person(){}
Person(){
Person(String name)
this.name=name;
}
Person(String name,int age)
this.name=name;
this.age=age;
}
//得到字节码
Class clazz=Class.forName("com.huida.reflect.Person");
//解剖属性
//只能得到public修饰的成员属性
Field[] fields=clazz.getFields(); 得到全部属性(数组)
//暴力反射 拿到所以得属性
Field[] fields=clazz.getDeclaredFields();( 数组)
Field f=clazz.getField("name"); 得到指定的单一属性(单个字段)
Field f1=clazz.getDeclaredField("age"); 都封装成一个对象f (以字符串的形式表现出去)
//高级for循环遍历
for(Field f:fields){
syso(f);
第三步 要解剖构造方法(三个):(API中 class中的方法)
//得到字节码
Class clazz=Class.forName("com.huida.reflect.Person");
//得到构造方法 public 修饰的
Constructor[] cons= clazz.getConstructors();
//高级for循环遍历
for(Constructor con: cons){
syso(con);
}
//暴力反射 Declared 得到所有的构造方法
Constructor[] cons= clazz.getDeclaredConstructors();
高级for循环遍历
//getConstructor(Class<?>... parameterTypes) 得到单个的构造方法
//...代表参数个数不固定(class类型的参数)
Constructor con= clazz.getConstructor(); //得到空参的构造方法
//暴力反射可以得到所有的构造函数 + 必须加 参数类型和个数确定解剖哪个构造方法
clazz.getDeclaredConstructor(String.class); //这里的参数是形参
clazz.getDeclaredConstructor(String.class,int.class);
知识:
一个类中创建对象需要构造方法,构造方法可以初始化对象,构造方法就是来创建对象的
一般类来说 创建对象
第一步 写一个类 class Person{}
第二步 创建对象erson p=new Person();(利用构造方法)
第三步 写构造方法 供上面对象使用
现在用反射创建对象:
第一步 解剖类
第二步 得到构造方法 ,把构造方法封装成对象
第三步 构造方法来创建对象
Object obj=(Person)con newInstance(“”); //这“”中加的是实参
//利用无参的构造方法 创建了一个对象,必须*强转*成此解剖类
第四,解剖类中的普通方法(三个普通方法):
public void show(){
syso();
}
public void method(){
syso();
}
public void method(){
syso();
}
首先还是获取到字节码;
Class clazz=Class.forName("com.huida.reflect.Person");
得到所有的方法,不只是三个,还有继承父类中的方法
Method[] methods=clazz.getMethods();
for(Method method:methods){
syso();
}
//得到本类中所有的方法(自己写的三个方法)
Method[] methods=clazz.getDeclaredMethods();
//得到一个方法(方法名+参数 ) (把方法封装成对象)
Method method =clazz.getMethod("method",null);method方法 ,无参数的
Method method1 =clazz.getMethod("method",int.class); 有一个int参数
知识:方法是用来运行的
原来一般调用方法 → 创建一个对象 → 对象.方法
现在用反射把方法封装成一个对象 →
invoke激活启动运行方法 但是里面需要传本类对象+方法的参数,没有参数用null
method.invoke(clazz.newInstance(),null);
method1.invoke(clazz.newInstance(),20);
类:属性 方法 构造方法
java原文件 javac编译 生成class(字节码文件,真正在内存中运行的东西)
用反射解剖类
第一步首先要得到类的字节码文件(得到方式三种) :
1. 类名.class 返回class类型 (万物皆对象,字节码文件也是对象)
Class clazz = Person.class;
syso(clazz); // 可以看一下字节码
2. 对象.getClass();
Person p=new Person(); //创建一个对象
Class clazz=p.getClass(); //在一个.java 文件中 这个clazz 和上面那个clazz相等
//不管怎么得到 ,都是那一个
3.(常用)class.forName(类名);//传全路径类名 包名+类名
Eclipse中快速复制类的全路径名字:
选中 右键 选择” Copy Qualified Name“ Ctrl+v粘贴就ok
Class clazz=Class.forName("com.huida.reflect.Person");
为什么用第三种:可扩展性强
(定义一个方法,只要用户把全路径传进来就可以得到字节码文件)
第二步要解剖类中的属性(字段 Field):(API中 用class类中的方法)
例子:解剖Person中的属性
Class Person{
//属性
String name;//默认的是default
//public String name;
//private int age;
//protected boolean sex;
//构造方法(三个构造方法)
public Person(){}
Person(){
Person(String name)
this.name=name;
}
Person(String name,int age)
this.name=name;
this.age=age;
}
//得到字节码
Class clazz=Class.forName("com.huida.reflect.Person");
//解剖属性
//只能得到public修饰的成员属性
Field[] fields=clazz.getFields(); 得到全部属性(数组)
//暴力反射 拿到所以得属性
Field[] fields=clazz.getDeclaredFields();( 数组)
Field f=clazz.getField("name"); 得到指定的单一属性(单个字段)
Field f1=clazz.getDeclaredField("age"); 都封装成一个对象f (以字符串的形式表现出去)
//高级for循环遍历
for(Field f:fields){
syso(f);
}
第三步 要解剖构造方法(三个):(API中 class中的方法)
//得到字节码
Class clazz=Class.forName("com.huida.reflect.Person");
//得到构造方法 public 修饰的
Constructor[] cons= clazz.getConstructors();
//高级for循环遍历
for(Constructor con: cons){
syso(con);
}
//暴力反射 Declared 得到所有的构造方法
Constructor[] cons= clazz.getDeclaredConstructors();
高级for循环遍历
//getConstructor(Class<?>... parameterTypes) 得到单个的构造方法
//...代表参数个数不固定(class类型的参数)
Constructor con= clazz.getConstructor(); //得到空参的构造方法
//暴力反射可以得到所有的构造函数 + 必须加 参数类型和个数确定解剖哪个构造方法
clazz.getDeclaredConstructor(String.class); //这里的参数是形参
clazz.getDeclaredConstructor(String.class,int.class);
知识:
一个类中创建对象需要构造方法,构造方法可以初始化对象,构造方法就是来创建对象的
一般类来说 创建对象
第一步 写一个类 class Person{}
第二步 创建对象erson p=new Person();(利用构造方法)
第三步 写构造方法 供上面对象使用
现在用反射创建对象:
第一步 解剖类
第二步 得到构造方法 ,把构造方法封装成对象
第三步 构造方法来创建对象
Object obj=(Person)con newInstance(“”); //这“”中加的是实参
//利用无参的构造方法 创建了一个对象,必须*强转*成此解剖类
第四,解剖类中的普通方法(三个普通方法):
public void show(){
syso();
}
public void method(){
syso();
}
public void method(){
syso();
}
首先还是获取到字节码;
Class clazz=Class.forName("com.huida.reflect.Person");
得到所有的方法,不只是三个,还有继承父类中的方法
Method[] methods=clazz.getMethods();
for(Method method:methods){
syso();
}
//得到本类中所有的方法(自己写的三个方法)
Method[] methods=clazz.getDeclaredMethods();
//得到一个方法(方法名+参数 ) (把方法封装成对象)
Method method =clazz.getMethod("method",null);method方法 ,无参数的
Method method1 =clazz.getMethod("method",int.class); 有一个int参数
知识:方法是用来运行的
原来一般调用方法 → 创建一个对象 → 对象.方法
现在用反射把方法封装成一个对象 →
invoke激活启动运行方法 但是里面需要传本类对象+方法的参数,没有参数用null
method.invoke(clazz.newInstance(),null);
method1.invoke(clazz.newInstance(),20);