反射的基本知识总结
1.定义
在运行期间,可以获取对象的类型,类型的方法,类型的属性,类型的构造等等。让对象可以认识到自身的结构。
2 获取对象的类型:(类对象)
方式1:Object 中的 .getClass();例如:new User().getClass();
方式2:Class.forName(”类名”);注;类名在这要写上包名,即完整的类名
方式3:类名.class;
这个类型信息在jvm中只存储一份。故三种方式得到的类都是同一个。
代码:
Class<?> clazz1 = new User().getClass();
Class<?> clazz1 = new User().getClass();
Class<?> clazz2 = Class.forName("com.westos.reflect.User");
Class<?> clazz3=User.class;
3类对象的功能
1).用反射方式创建对象
类对象.newInstance();//创建一个新实例
限制:1.要求对象有无参构造,2.构造不能私有(注意:当构造私有时,可以反射重新获取构造方法,破坏掉私有构造,采用构造器做类对象创建实例)。
代码如下://用反射方式创建对象
Object o = clazz1.newInstance();
User user=(User) o;
user.m2(3);
2).获取方法信息
类对象.getMethods();//获取所有公共方法(public),包括继承的
类对象.getDeclaredmethods();//包括本类的所有方法(pubic ,private,proteced,不加)
类对象.getMethod(方法名,参数类型);//找公共的方法,包括继承的
类对象.getDeclaredmethod(方法名,参数类型);//找本类的方法
3)获取属性信息(了解)
类对象.getFields();//获取所有公共的属性
类对象.getDeclaredFields();//获取本类中的所有属性
类对象.getField(“属性名”);//获取公共的属性
类对象.getDeclaredField(“属性名”);//获取本类中的指定的所有属性
4)获取构造方法(了解)
类对象.getConstructors();//获取所有的公共的构造方法
类对象.getDeclaredConstructor();//获取本类中的所有构造方法
类对象.getConstructor(int.c lass);//获取int 参数类型的构造
类对象.getConstructor();//获得无参构造
5)反射调用方法(重要)
反射调用方式:方法.invoke(对象,参数);
缺点:调用复杂,效率 低
优点:可以调用私有方法,突破正常方法的限制,经常用在开源框架中。
Student student = Student.class.newInstance();
Method m11 = Student.class.getDeclaredMethod("m1",int.class);
System.out.println(m11);
m11.setAccessible(true);//设置这个方法可以被访问
m11.invoke(student, 2);
Method m22 = Student.class.getDeclaredMethod("m2");
m22.setAccessible(true);
m22.invoke(student);
以上完整代码:
public class UserTest {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, NoSuchFieldException, InvocationTargetException {
//反射获取类对象的三种方式
Class<?> clazz1 = new User().getClass();
Class<?> clazz2 = Class.forName("com.westos.reflect.User");
Class<?> clazz3=User.class;
System.out.println(clazz1==clazz2);
System.out.println(clazz2==clazz3);
//用反射方式创建对象
Object o = clazz1.newInstance();
User user=(User) o;
user.m2(3);
//获取方法信息
Method[] methods = clazz1.getMethods();//获取所有公共方法(包括继承的方法)
for(Method method:methods){
System.out.println(method);
}
System.out.println("=========================");
Method[] declaredMethods = clazz1.getDeclaredMethods();//获取本类中所有的方法(private public protected)
for(Method m:declaredMethods){
System.out.println(m);
}
clazz1.getMethod("setAge", int.class);//找带有参数和参数类型的公共方法,包括继承的方法
clazz1.getDeclaredMethod("m2",int.class);//找本类中所有符合的方法
//获取属性信息
Field[] fields = clazz1.getFields();//获取所有公共属性
for(Field f:fields){
System.out.println(f);
}
Field[] declaredFields = clazz1.getDeclaredFields();//获取本类中的所有属性
for(Field f1:declaredFields){
System.out.println(f1);
}
clazz1.getField("age");//获取指定属性名的公共属性
clazz1.getDeclaredField("age");//获取指定属性名的本类中的属性
//获取构造方法
//获取所有的公共的构造方法
for (Constructor<?> constructor : clazz1.getConstructors()) {
System.out.println(constructor);
}
//获取本类中的所有构造方法
clazz1.getDeclaredConstructors();
//获取指定参数类型的构造方法
clazz1.getConstructor(String.class,int.class);
//无参构造
clazz1.getConstructor();
}
}
public class User {
private String name;
public int age;
public User(){}
public User(String name,int age){
this.age=age;
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void m1(){}
public void m2(int a){
System.out.println("有参方法执行了");
}
}
public class TestStudent {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException
//反射调方法
//反射调用方法形式 方法.invoke(对象,参数)
Student student = Student.class.newInstance();
Method m11 = Student.class.getDeclaredMethod("m1",int.class);
System.out.println(m11);
m11.setAccessible(true);//设置这个方法可以被访问
m11.invoke(student, 2);
Method m22 = Student.class.getDeclaredMethod("m2");
m22.setAccessible(true);
m22.invoke(student);
}
}
public class Student {
private String name;
private int age;
private void m1(int a){
System.out.println("m1私有方法执行了");
}
public void m2(){
System.out.println("m2方法执行了");
}
}