目录
setAccessible(true) newInstance
1.反射概述
1.1 反射引入
-
回忆一下之前如何使用一个Java类?
-
已知一个类的类名、以及类中的方法、属性、构造方法等
-
调用构造方法创建对象
-
使用对象调用方法或属性
-
-
问题:
-
如果仅仅知道一个类的类名,能否动态得到类的定义信息,包括哪些方法,属性等?
-
-
答案:可以通过反射做到
1.2 Java反射的概念
-
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
-
如果做到的呢?
当一个字节码文件加载到内存的时候,jvm会对该字节码进行解剖,然后创建一个对象的Class对象,把字节码文件的信息全部都存储到该Class对象中,我们只要获取到Class对象,我们就可以使用字节码对象设置对象的属性或者调用对象的方法等操作。
1.3 Java反射的作用
-
动态获取类的信息,进一步实现需要的功能
-
例如:Spring框架通过XML文件描述类的基本信息,使用反射机制动态装配对象
1.4 Java反射相关的类
-
Java反射相关的类主要包括
-
Class 类型
-
Constructor 构造方法
-
Method 方法
-
Field 属性
-
……
-
除了Class外,其他类都位于java.lang.reflect包中
-
-
可见,反射API将类的类型、方法、属性都封装成了类
-
其中最重要的类是Class,可以说,反射的使用都是从Class开始
2.Class类的使用
-
如何获得Class实例?为一个class生成对应的Class对象
-
案例
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void aa() {
System.out.println("aa");
}
public void aa(String str) {
System.out.println("aa" + str);
}
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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import java.util.HashMap;
public class ReflectTest {
public static void main(String[] args) {
System.out.println("------对象名.getClass()-------");
//1、对象名.getClass()获取Person对象p对应的类的Class对象
//获取p对象对应的类(Person)的Class对象
Person p = new Person("jack", 20);
Class pClazz = p.getClass();
System.out.println(pClazz);
/*输出:class com.bx.reflect.Person*/
String str = "abc";
Class strClazz = str.getClass();
System.out.println(strClazz);
/*输出:class java.lang.String*/
System.out.println("------对象名.getSupperClass-------");
//2、对象名.getSupperClass
Class pClazzClass = pClazz.getClass();
System.out.println(pClazzClass);
/*输出:class java.lang.Class*/
Class superclass = pClazz.getSuperclass();
System.out.println(superclass);
/*输出:class java.lang.Object*/
System.out.println("------Class.forName()-------");
//3、Class.forName()
try {
//Class.forName()字符串,没有定义字符串对应的类名,会抛出异常
//Class personClazz = Class.forName("com.bx.reflect.Person111");
Class personClazz = Class.forName("com.bx.reflect.Person");
System.out.println(personClazz);
/*输出:class com.bx.reflect.Person*/
Class stringClazz = Class.forName("java.lang.String");
System.out.println(stringClazz);
/*输出:class java.lang.String*/
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("--------类名.class--------");
//4、类名.class
Class hashMapClass = HashMap.class;
System.out.println(hashMapClass);
/*输出:class java.util.HashMap*/
Class personClass = Person.class;
System.out.println(personClass);
/*输出:class com.bx.reflect.Person*/
}
}
-
Class类是Java反射机制的基础,通过Class类,可以得到一个类的基本信息。以下类是Class类的常用方法:
-
案例
Person类
public class Person {
public String puEmail;
private String name;
private int age;
//私有构造方法
private Person(int age, String name) {
this.age = age;
this.name = name;
}
public Person() {
}
public Person(String name) {
this.name = name;
}
public Person(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String puEmail, String name) {
this.puEmail = puEmail;
this.name = name;
}
public Person(String puEmail, Str