什么是反射
相对官方解释
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力;
在运行时期,动态地去获取类中的信息(类的信息,方法信息,构造器信息,字段等信息); 在运行的时候获取到的类信息 封装一个字节码对象
反射功能
由于后续均会以代码演示,故此处先行写出后续要用的User类
public class User {
private String name;
private String password;
public User(String name,String password){
this.name=name;
this.password=password;
}
public User(){
}
private User(String name){
}
public String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
private void test(String s){
System.out.println("这是私有的测试方法,外人无法访问");
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
获取构造方法
public class MyTest {
public static void main(String[] args) throws Exception {
// System.out.println(User.class);
// User user=new User();
// System.out.println(user.getClass());
Class<?> a=Class.forName("com.WEB.Reflect._02Reflect.User");
System.out.println(a);
//假定一个非自身类
//因为私有属性爆红
// Shoe.class;
// new Shoe().getClass();
// System.out.println("com.WEB.Reflect._02Reflect.Shoe");
//获取a当中所有的共有构造
Constructor<?> [] constructors=a.getConstructors();//获取所有共有构造
System.out.println(constructors);
// 获取所有声明了的构造
Constructor<?>[] constructors=a.getDeclaredConstructors();//获取所有声明了的构造,私有公有都会出现
for (Constructor<?> constructor:constructors){
System.out.println(constructor);
}
}
}
上述的getConstructors()只能获取公共构造,即被public修饰的构造;而getDeclaredConstructors()能够获取所有被声明的构造,即无论公共还是私有,都能够被获取。
让访问权限失效
public class MyTest {
public static void main(String[] args) throws Exception {
// System.out.println(User.class);
// User user=new User();
// System.out.println(user.getClass());
Class<?> a=Class.forName("com.WEB.Reflect._02Reflect.User");
System.out.println(a);
//假定一个非自身类
//因为私有属性爆红
// Shoe.class;
// new Shoe().getClass();
// System.out.println("com.WEB.Reflect._02Reflect.Shoe");
//获取a当中所有的共有构造
Constructor<?> [] constructors=a.getConstructors();//获取所有共有构造
System.out.println(constructors);
// 获取所有声明了的构造
// Constructor<?>[] constructors=a.getDeclaredConstructors();//获取所有声明了的构造,私有公有都会出现
// for (Constructor<?> constructor:constructors){
// System.out.println(constructor);
// }
Constructor<?> constructor = a.getConstructor(String.class, String.class);
Object o = constructor.newInstance("Lily", "123456");
Constructor<?>[] constructor1=a.getDeclaredConstructor(String.class);
constructor.setAccessible(true);//破坏访问权限
System.out.println(constructor1.newInstance("123"));
}
}
重要语句就是constructor.setAccessible(true);设置为true,即可破解访问权限,无论公有还是私有方法均可用。
获得方法
public class MyTest {
public static void main(String[] args) throws Exception {
// System.out.println(User.class);
// User user=new User();
// System.out.println(user.getClass());
Class<?> a=Class.forName("com.WEB.Reflect._02Reflect.User");
System.out.println(a);
//假定一个非自身类
//因为私有属性爆红
// Shoe.class;
// new Shoe().getClass();
// System.out.println("com.WEB.Reflect._02Reflect.Shoe");
//获取a当中所有的共有构造
Constructor<?> [] constructors=a.getConstructors();//获取所有共有构造
System.out.println(constructors);
// 获取所有声明了的构造
// Constructor<?>[] constructors=a.getDeclaredConstructors();//获取所有声明了的构造,私有公有都会出现
// for (Constructor<?> constructor:constructors){
// System.out.println(constructor);
// }
Constructor<?> constructor = a.getConstructor(String.class, String.class);
Object o = constructor.newInstance("Lily", "123456");
// Constructor<?>[] constructor1=a.getDeclaredConstructor(String.class);
// constructor.setAccessible(true);//破坏访问权限
// System.out.println(constructor1.newInstance("123"));
//获取方法
Method[] methods =a.getMethods();//获取所有共有方法
for (Method method:methods){
System.out.println(method);
}
Method[] methods1=a.getDeclaredMethods();//获取所有方法包括私有
for (Method method:methods1){
System.out.println(method);
}
Method method=a.getDeclaredMethod("test", String.class);
method.setAccessible(true);
//用反射调用方法
method.invoke(o,"hello");
}
}
同样此处也是通过getMethods()与getDeclaredMethods()
获取字段
public class MyTest {
public static void main(String[] args) throws Exception {
// System.out.println(User.class);
// User user=new User();
// System.out.println(user.getClass());
Class<?> a=Class.forName("com.WEB.Reflect._02Reflect.User");
System.out.println(a);
//假定一个非自身类
//因为私有属性爆红
// Shoe.class;
// new Shoe().getClass();
// System.out.println("com.WEB.Reflect._02Reflect.Shoe");
//获取a当中所有的共有构造
Constructor<?> [] constructors=a.getConstructors();//获取所有共有构造
System.out.println(constructors);
// 获取所有声明了的构造
// Constructor<?>[] constructors=a.getDeclaredConstructors();//获取所有声明了的构造,私有公有都会出现
// for (Constructor<?> constructor:constructors){
// System.out.println(constructor);
// }
Constructor<?> constructor = a.getConstructor(String.class, String.class);
Object o = constructor.newInstance("Lily", "123456");
// Constructor<?>[] constructor1=a.getDeclaredConstructor(String.class);
// constructor.setAccessible(true);//破坏访问权限
// System.out.println(constructor1.newInstance("123"));
//获取方法
Method[] methods =a.getMethods();//获取所有共有方法
for (Method method:methods){
System.out.println(method);
}
Method[] methods1=a.getDeclaredMethods();//获取所有方法包括私有
for (Method method:methods1){
System.out.println(method);
}
Method method=a.getDeclaredMethod("test", String.class);
method.setAccessible(true);
//用反射调用方法
method.invoke(o,"hello");
//获取属性
// Field[] fields=a.getDeclaredFields();
// for (Field field:fields){
// System.out.println(field);
// }
Field field=a.getDeclaredField("name");
field.setAccessible(true);
field.set(o,"123");
System.out.println(field.get(o));
}
}
同样此处也是通过getField()与getDeclaredFields()来获取共有和所有字段。
写在最后:反射是JAVA中很重要的一个机制,后期的SpringBoot,Mybatis均都是用到了反射。笔者小,中,大厂面试均有面试经历,坚持每日分享JAVA全栈知识,希望和大家共同进步。