java__反射个人总结

java反射个人总结

1.文字概述
个人认为反射就是指: 在运行时通过代码操作类。
通过三种获取class类字节码文件对象后使用newInstance() 方法调用class对象空参构造方法创建实例对象
使用class对象调用getConstructor(new Class[]{String.class, int.class})方法获取有参构造方法创建Constructor对象,并使用Constructor对象调用newInstance()创建实例对象;
使用class对象调用getMethod(““方法名”,参数.class)方法获取class对象中的method方法对象,并使用class对象调用newInstance()方法创建实例对象method方法对象调用invoke(实例对象,“参数”)方法,进行参数传递以及方法的执行;
使用class对象调用getFiled(“属性名”) 获取属性对象,并使用class对象调用newInstance()方法创建实例对象属性对象调用set(实例对象,“参数”)方法进行参数的操作;
2. 对私有有参构造,私有方法,静态方法,私有属性的操作
使用class对象调用getDeclaredConstructor(new Class[]{String.class, int.class})方法获取私有的有参构造方法创建Constructor对象,同时对Constructor对象设置setAccessible(true)暴力访问权限,并调用newInstance(new Object[]{"Jack", 30, "学霸")创建实例对象;
使用class对象调用getDeclaredMethod(“方法名”,参数.class)方法获取class对象私有的method方法对象,同时对method方法对象设置setAccessible(true)暴力访问权限,并调用invoke(obj, 100)方法进行参数以及方法的执行;
使用class对象调用 getMethod("main",new Class[]{String[].class}) 方法获取class对象中的静态method方法对象,并使用class对象调用newInstance()方法创建实例对象method方法对象调用invoke(null, new Object[]{new String[]{“Hello”, “World”}})方法,进行参数传递以及方法的执行;
使用class对象调用getDeclaredFiled(“属性名”) 获取属性对象,并使用属性对象设置setAccessible(true)暴力访问权限,属性对象调用set(实例对象,“参数”)方法进行参数的操作;
3.实际举例说明

// 提供 Student 类, 用于之后的反射操作.

public class Student {
public static void main(String[] args) {
System.out.println("Student 类的 main 方法被调用… ");
System.out.println(“args[0]=” + args[0] + “, args[1]=” + args[1]);
}
// 属性
private String name;
private int age;
public String description;
// 无参构造方法
public Student() {
System.out.println(“无参构造方法被调用…”);
}
public Student(String name, int age) {
System.out.println(“带 String name, int age 参数的构造方法被调用…”);
this.name = name;
this.age = age;
}
// 私有构造方法
private Student(String name, int age, String description) {
System.out.println(“私有构造方法被调用…”);
this.name = name;
this.age = age;
this.description = description;
}
// 私有方法
private void show(int num) {
System.out.println("私有方法: " + num);
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
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 “Student [name=” + name + “, age=” + age + “, description=” + description + “]”;
}
}
4.反射调用构造创建对象
在这里插入图片描述
package cn.itcast.reflect;

import java.lang.reflect.Constructor;

import org.junit.Test;

public class ConstructorDemo {
// 普通方式 : 直接 new 对象.
@Test
public void demo01() {
// 触发 无参构造方法
// Student stu = new Student();

// 触发 `有参构造方法`
// Student stu = new Student("Jack", 30);

// 触发 `私有构造方法` 错误!
// Student stu = new Student("Jack", 30, "学霸");
// System.out.println(stu);

}

// 通过反射调用无参构造方法获得实例对象
@Test
public void demo02() throws Exception {
// 1. 获取Class对象
Class<?> cls = Class.forName(“cn.itcast.reflect.Student”);
// 2. 通过cls直接创建对象, 相当于: new Student();
Object obj = cls.newInstance();
}

// 通过反射调用有参构造方法, 获得实例对象
@Test
public void demo03() throws Exception {
// 1. 获取Class对象
Class<?> cls = Class.forName("cn.itcast.reflect.Student"); // 2. 获得构造方法, 相当于: Student(String name, int age); // getConstructor(Class<?>… parameterTypes)
Constructor<?> cons = cls.getConstructor(new Class[]{String.class, int.class});
// 3. 调用构造方法, 获得实例对象, 相当于: new Student();
// newInstance(Object … initargs)
Object obj = cons.newInstance(new Object[]{“Jack”, 30});
System.out.println(obj);
}

// 通过私有构造方法获得实例对象
@Test
public void demo04() throws Exception {
// 1. 获取 Class 对象
Class<?> cls = Class.forName("cn.itcast.reflect.Student"); // 2. 获取构造方法 Constructor<?> cons = cls.getDeclaredConstructor(new Class[]{String.class, int.class, String.class});
// 暴力访问 (默认不允许)
cons.setAccessible(true);
// 3. 调用构造方法, 获得实例对象
Object obj = cons.newInstance(new Object[]{“Jack”, 30, “学霸”});
System.out.println(obj);
}
}
5.使用反射执行方法
在这里插入图片描述
package cn.itcast.reflect;

import java.lang.reflect.Method;

import org.junit.Test;

public class MethodDemo {
@Test
public void demo01() {
Student stu = new Student();
stu.setName(“Jack”);
stu.setAge(30);
System.out.println(stu);
String name = stu.getName();
int age = stu.getAge();
System.out.println("name: " + name + ", age: " + age);
// stu.show(); 错误! 无法调用私有方法.
}
@Test
public void demo02() throws Exception {
// 1. 获得实例
Class<?> cls = Class.forName(“cn.itcast.reflect.Student”);
Object obj = cls.newInstance();
// 2.1 获取 setName(String name) 方法
Method setNameMethod = cls.getMethod(“setName”, String.class);
// 2.2 调用方法, 传递实际参数
setNameMethod.invoke(obj, “Jack”);
// 2.3 获取 setAge(int age) 方法
Method setAgeMethod = cls.getMethod(“setAge”, int.class);
// 2.4 调用
setAgeMethod.invoke(obj, 30);
System.out.println(obj);

// Method getNameMethod = cls.getMethod(“getName”, null);
// Object name = getNameMethod.invoke(obj, null);
// Method getAgeMethod = cls.getMethod(“getAge”, null);
// Object age = getAgeMethod.invoke(obj, null);
Method getNameMethod = cls.getMethod(“getName”);
Object name = getNameMethod.invoke(obj);
Method getAgeMethod = cls.getMethod(“getAge”);
Object age = getAgeMethod.invoke(obj);
System.out.println("name: " + name + ", age: " + age);
}
@Test
public void demo03() throws Exception {
// 1. 获得实例
Class<?> cls = Class.forName("cn.itcast.reflect.Student"); Object obj = cls.newInstance(); // 2. 获取方法并调用执行 Method showMethod = cls.getDeclaredMethod("show", int.class); showMethod.setAccessible(true); // 暴力访问 Object result = showMethod.invoke(obj, 100); // 如果方法没有返回结果, 那么结果为 null System.out.println(result); } // 执行静态方法 main, 无需获得实例, 但是必须要获得 Class 对象 @Test public void demo04() throws Exception { // 1. 获得 Class 对象 Class<?> cls = Class.forName(“cn.itcast.reflect.Student”);
// 2. 获得 main 方法
Method mainMethod = cls.getMethod(“main”, new Class[]{String[].class});
// 特点注意 : 数组类型的参数书写格式
mainMethod.invoke(null, new Object[]{new String[]{“Hello”, “World”}});
}
}

可变参数的方法调用方式 :

在这里插入图片描述
6.使用反射获取属性
在这里插入图片描述
package cn.itcast.reflect;
import java.lang.reflect.Field;
import org.junit.Test;
public class FieldDemo {
@Test
public void demo01() {
Student stu = new Student();
stu.description = “描述信息”;
System.out.println(stu);
}
@Test
public void demo02() throws Exception {
// 1. 获得实例
Class<?> cls = Class.forName("cn.itcast.reflect.Student"); Object obj = cls.newInstance(); // 2. 获得属性 Field descField = cls.getField("description"); descField.set(obj, "描述信息: 学霸"); System.out.println(obj); } @Test public void demo03() throws Exception { // 1. 获得实例 Class<?> cls = Class.forName(“cn.itcast.reflect.Student”);
Object obj = cls.newInstance();
// 2. 获得属性并设置数值
Field nameField = cls.getDeclaredField(“name”);
nameField.setAccessible(true);
nameField.set(obj, “Jack”);
Field ageField = cls.getDeclaredField(“age”);
ageField.setAccessible(true);
ageField.set(obj, 30);
System.out.println(obj);
// 查看属性
Object name = nameField.get(obj);
Object age = ageField.get(obj);
System.out.println("name: " + name + ", age: " + age);
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值