Java反射
反射也叫自省,其名称来源于光学上的反射概念: ?
人通过照镜子来知道自己的样子 ?
Java对象通过反射知道自己的类型等信息 ?
我们其实经常使用最基本的自省操作: ?
instanceof 操作符 ?
Object.getClass() 方法
JAVA不是动态语言,但JAVA具有一个突出的动态语言机制:反射
反射的反射机制是指程序运行时动态自检的能力:
- 能够获得任意一个类的全部信息,包含其属性和方法
- 能够任意访问一个对象的属性和方法
反射能让你执行一些正常情况下无法实现的操作:
- 访问私有属性和私有方法
- 不通过new关键字,而通过类名来实例化对象
JAVA反射API在:java.lang.reflect包下,常用有四个:
- Class:表示反射的核心类
- Method:表示类的方法
- Filed:表示类的属性
- Constructor:表示类的构造方法
反射核心类 - Class
Class是所有反射功能的入口,使用反射的第一步是要获得Class对象:
1、如果持有对象的引用,则可以通过getClass()方法获取它的类对象
User user1 = new User();
Class<? extends User> class1 = user1.getClass();
2、如果在编译期就知道具体的类型,则可以通过 类名.class 的方法来获取类对象
Class<User> User = User.class;
3、如果在运行时知道类名,则可以通过Class.forName(Str)静态方法获取类对象
Class<User> forName = (Class<User>) Class.forName("com.fanshe.User");
用Constructor创建对象
使用反射创建对象有两种方法: ?
如果该类有无参构造方法,可以使用Class.newInstance()方法 ?
第一种方式:newInstance( ):适用于无参构造
User is = User.newInstance();
is.setAge(25);
is.setHeight("175");
is.setName("bobo");
System.out.println(is);
第二种方式:getConstructor( ):适用于所有公共的构造
Constructor<com.fanshe.User> constr = User.getConstructor(String.class,String.class,int.class);
com.fanshe.User user2 = constr.newInstance("coco","177",25);
System.out.println(user2.toString());
第三种方式:getDeclaredConstructor():适用于所有构造 (暴力)
Constructor<com.fanshe.User> constr1 = User.getDeclaredConstructor(String.class,String.class,int.class);
//设置允许访问私有
constr1.setAccessible(true);
User user3 = constr1.newInstance("wowo","188",22);
System.out.println(user3);
//获取公共的属性
Field field = User.getField("name");
System.out.println(field);
System.out.println(field.getName());
System.out.println(field.getType());
//暴力获取私有属性
Field field2 = User.getDeclaredField("age");
field2.setAccessible(true);
System.out.println(field2);
System.out.println(field2.getName());
System.out.println(field2.getType());
//获取该属性的值
//obj:需要获取的目标对象
int age = (int) field2.get(user3);
System.out.println(age);
//反射获取方法
Method method = User.getMethod("getName");
String invoke = (String) method.invoke(user3);
System.out.println(invoke);
Class<User> user = User.class;
User in = user.newInstance();
in.setName("titi");
in.setAge(12);
//1.获取有参的方法
Method method = user.getMethod("setName", String.class);
String invoke = (String) method.invoke(in, "");
System.out.println(invoke);
//2、获取私有的方法
Method method1 = user.getDeclaredMethod("show");
method1.setAccessible(true);
method1.invoke(in);