反射(Reflection):加载类,并允许以编程的方式,解剖类中各种成分(成员变量、方法、构造器等)
获取Class对象的三种方式
(1)Class对象阶段(已经加载到内存)->Class c1=类名.class
(2)源码阶段(还没有加载到内存)->调用Class提供的方法:public static Class forName(String package)
(3)Runtime运行阶段(手动new对象时)->Object提供的方法:public Class getClass(); Class c3=对象.getClass()
public class Demo {
public static void main(String[] args) throws ClassNotFoundException {
//1、Class类的静态方法forName(String 全限定名);
Class c1 = Class.forName("com.demo04_reflect_获取类.Student");//全类名=包名+类名
System.out.println(c1.getName()); //com.demo04_reflect_获取类.Student
System.out.println(c1.getSimpleName()); //Student
//2、类名.class
Class c2 = Student.class;
System.out.println(c2.getName());
System.out.println(c2.getSimpleName());
//3、对象.getClass()
Student stu = new Student("张三", 18);
Class c3 = stu.getClass();
System.out.println(c3.getName());
System.out.println(c3.getSimpleName());
//这三个Class对象是不是一个对象?
System.out.println(c1 == c2);//true
System.out.println(c2 == c3);//true
}
}
Class提供了从类中获取构造器的方法
方法 | 说明 |
---|---|
Constructor>[] getConstructors() | 获取全部构造器(只能获取public修饰的) |
Constructor>[] getDeclaredConstructors() | 获取全部构造器(只要存在就能拿到) |
Constructor< T >[] getConstructors(Class>… parameterTypes) | 获取某个构造器(只能获取public修饰的) |
Constructor< T >[] getDeclaredConstructors(Class>… parameterTypes) | 获取某个构造器(只要存在就能拿到) |
获取类构造器的作用:依然是初始化对象返回
Constructor提供的方法 | 说明 |
---|---|
T newInstance(Object…initargs) | 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
实体类Cat:
public class Cat {
//公共空参
public Cat() {
}
//公共带参
public Cat(String name, int age) {
}
//私有带参
private Cat(String name) {
}
}
测试类:
public class Demo {
@Test
public void testGetDeclaredConstructor() throws NoSuchMethodException {
//加载类
Class clazz = Cat.class;
//获取单个指定的(只要存在,包含私有
Constructor c1 = clazz.getDeclaredConstructor(String.class);
System.out.println(c1); //private com.demo05_reflect_获取构造器对象.Cat(java.lang.String)
}
@Test
public void testGetConstructor() throws NoSuchMethodException {
Class clazz = Cat.class;
//获取单个指定的(公共的)
Constructor c1 = clazz.getConstructor();
System.out.println(c1); //public com.demo05_reflect_获取构造器对象.Cat()
Constructor c2 = clazz.getConstructor(String.class, int.class);
System.out.println(c2); //public com.demo05_reflect_获取构造器对象.Cat(java.lang.String,int)
}
@Test
public void testGetDeclaredConstructors() {
Class clazz = Cat.class;
//Constructor>[] getDeclaredConstructors(); 获取所有(只要存在,包含私有的)
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
//遍历数组
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
/*
public com.demo05_reflect_获取构造器对象.Cat()
public com.demo05_reflect_获取构造器对象.Cat(java.lang.String,int)
private com.demo05_reflect_获取构造器对象.Cat(java.lang.String)
*/
}
}
@Test
public void testGetConstructors() {
Class clazz = Cat.class;
//Constructor>[] getConstructors(); 获取所有(公共的)
Constructor[] constructors = clazz.getConstructors();
//遍历数组
for (Constructor constructor : constructors) {
System.out.println(constructor);
/*
public com.demo05_reflect_获取构造器对象.Cat()
public com.demo05_reflect_获取构造器对象.Cat(java.lang.String,int)
*/
}
}
}
通过构造器实例化对象
实体类Cat:
public class Cat {
private String name;
private int age;
//私有空参
private Cat() {
System.out.println("私有空参执行了...");
}
//公共带参
public Cat(String name, int age) {
System.out.println("公共带参执行了...");
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类:
public class Demo {
@Test //通过公共带参,创建对象
public void testNewInstance2() throws Exception {
//加载类
Class clazz = Cat.class;
//获取公共的带构造
Constructor constructor = clazz.getConstructor(String.class, int.class);
//T newInstance(参数1,参数2..); 通过构造器对象和指定参数,创建对象并返回(可强转为具体类型)
Cat cat = (Cat) constructor.newInstance("大橘", 5);
System.out.println(cat); //Cat{name='大橘', age=5}
}
@Test //通过私有空参,创建对象
public void testNewInstance1() throws Exception {
//加载类
Class clazz = Cat.class;
//获取私有的空参构造
Constructor constructor = clazz.getDeclaredConstructor();
//public void setAccessible(boolean flag); 参数为true表示禁止检查访问控制(暴力反射)
constructor.setAccessible(true); //禁止检查
//T newInstance(参数1,参数2..); 通过构造器对象和指定参数,创建对象并返回(可强转为具体类型)
Cat c = (Cat) constructor.newInstance();
System.out.println(c); //Cat{name='null', age=0}
}
}
Class提供了从类中获取成员变量的方法
方法 | 说明 |
---|---|
public Filed[] getFileds() | 获取类的全部成员变量(只能获取public修饰的) |
public Filed[] getDeclaredFileds() | 获取类的全部成员变量(只要存在就能拿到) |
public Filed getFiled(String name) | 获取类的某个成员变量(只能获取public修饰的) |
public Filed[] getDeclaredFiled(String name) | 获取类的某个成员变量(只要存在就能拿到) |
获取到成员变量的作用:依然是赋值、取值
方法 | 说明 |
---|---|
void set(Object obj,Object value) | 赋值 |
Object get(Object obj) | 取值 |
public void seAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
class Cat {
public static int number;
public static final String COUNTRY = "中国";
private String name;
private int age;
public Cat() {
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Demo {
//给成员变量赋值和取值
@Test
public void testGetAndSet() throws Exception {
Class clazz = Cat.class;
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
Cat c = new Cat();
String name = (String)field.get(c);
//System.out.println(name);
field.set(c,"daju");
String name1=(String)field.get(c);
System.out.println(name1);
}
@Test
public void testGetDeclaredField() throws NoSuchFieldException {
Class clazz = Cat.class;
System.out.println(clazz.getDeclaredField("name"));
}
@Test
public void testGetField() throws NoSuchFieldException {
Class clazz = Cat.class;
System.out.println(clazz.getField("number"));
}
@Test
public void testGetDeclaredFields() {
Class clazz = Cat.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
@Test
public void testGetFields() {
Class clazz = Cat.class;
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
}
}
Class提供了从类中获取成员方法的API
方法 | 说明 |
---|---|
Method[] getMethods() | 获取类的全部成员方法(只能获取public修饰的) |
Method getDeclaredMethods() | 获取类的全部成员方法(只要存在就能拿到) |
Method getMethod(String name,Class>…parameterTypes) | 获取类的某个成员方法(只能获取public修饰的) |
Method getDeclaredMethod(String name,Class>…parameterTypes) | 获取类的某个成员方法(只要存在就能拿到) |
成员方法的作用:依然是执行
Method提供的方法 | 说明 |
---|---|
public Object invoke(Object obj,Object…args) | 触发某个对象的方法执行 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
class Cat {
private String name;
private int age;
public Cat() {
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
//公共,无参无返
public void play() {
System.out.println("小猫捉迷藏");
}
//私有,有参有返
private String eat(String food) {
return "小猫爱吃" + food;
}
//公共,无参有返
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Demo {
@Test
public void testGetDeclaredMethod() throws Exception {
Class clazz = Cat.class;
Method declaredMethod = clazz.getDeclaredMethod("eat", String.class);
Cat c = (Cat)clazz.newInstance();
declaredMethod.setAccessible(true);
Object invoke = declaredMethod.invoke(c, "maotiao");
System.out.println(invoke);
}
@Test
public void testGetMethod() throws Exception{
Class clazz = Cat.class;
Method method = clazz.getMethod("play");
Cat c = (Cat) clazz.newInstance();
method.invoke(c);
}
@Test
public void testGetDeclaredMethods() throws Exception {
Class clazz = Cat.class;
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
}
@Test
public void testGetMethods() {
Class clazz = Cat.class;
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
}
}