反射基本概念?
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。Java 反射机制是在进行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法。
什么是 Java 反射机制?
Java 程序启动后, 首先把 .java 源码编译成 .class 字节码, 然后再把 .class 字节码加载到 JVM 中运行. 当我们 new 一个对象时, Java 在代码编译期就已经知道对象类型了, 然后在运行期创建该对象. 而 Java 反射机制是在运行期反向地创建对象, 获取属性和方法, 其在编译期不知道对象类型. Java 反射常用于各种框架中, 如 Spring 中获取对象的过程:
<!--定义bean-->
<beans
<bean id="userId" class="com.tyshawn.domain.User"></bean>
</beans>
//这里读取xml配置文件, 获取到"com.tyshawn.domain.User", 然后通过反射创建对象
User user = (User) context.getBean("userId");
Java 反射的基本使用
User 实体类
public class User {
public String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public void say(){
System.out.println("Hello " + this.getName());
}
public void say(String name){
System.out.println("Hello " +name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
获取 Class 类
(1) Class.forName()
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
(2) 类.class
Class<User> clazz = User.class;
(3) Object.getClass()
User user = new User();
Class<? extends User> clazz = user.getClass();
最常用的是第一种, 后面两种没啥意义.
创建实例
(1) 调用 Class 对象的 newInstance()方法
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
User user = (User) clazz.newInstance(); //只有无参构造
(2) 调用构造对象的 newInstance()方法
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
//无参构造
Constructor<?> constructor = clazz.getConstructor();
User user = (User) constructor.newInstance();
//有参构造
Constructor<?> constructor1 = clazz.getConstructor(String.class, Integer.class);
User user1 = (User) constructor1.newInstance("tyshawn", 23);
获取成员变量
(1) 获取公有成员变量
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
User user = (User) clazz.newInstance();
//获取共有成员变量
Field name = clazz.getField("name");
//赋值
name.set(user, "tyshaw");
System.out.println(user);
(2) 获取私有成员变量
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
User user = (User) clazz.newInstance();
//获取共有成员变量
Field age = clazz.getDeclaredField("age");
//去除私有权限
age.setAccessible(true);
//赋值
age.set(user, 23);
System.out.println(user);
获取成员方法
(1) 获取公有成员方法
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
User user = (User) constructor.newInstance("Tyshawn", 23);
//获取无参成员方法
Method say = clazz.getMethod("say");
say.invoke(user); // Hello Tyshawn
//获取有参成员方法
Method say1 = clazz.getMethod("say", String.class);
say1.invoke(user, "Tom"); //Hello Tom
(2) 获取私有成员方法
Class<?> clazz = Class.forName("com.tyshawn.domain.User");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
User user = (User) constructor.newInstance("Tyshawn", 23);
//获取无参成员方法
Method method = clazz.getDeclaredMethod("say");
//去除私有权限
method.setAccessible(true);
method.invoke(user); // Hello Tyshawn
//获取有参成员方法
Method method1 = clazz.getDeclaredMethod("say", String.class);
//去除私有权限
method1.setAccessible(true);
method1.invoke(user, "Tom"); //Hello Tom