反射
反射
1、反射的定义
什么是反射?
反射允许对成员变量,成员方法和构造方法的信息进行编程访问
2、反射的操作
2.1 获取class对象
获取class对象的三种方式
1、Class.forName("全类名");
2、类名.class
3、对象.getClass();
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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 +
'}';
}
}
public class Demo02_1 {
public static void main(String[] args) throws ClassNotFoundException {
//1、Class.forName("全类名")
//单独的T 代表一个类型 ,而 Class<T>代表这个类型所对应的类, Class<?>表示类型不确定的类
Class<?> clazz = Class.forName("com.hu.demo02.Person");
System.out.println(clazz);
//2、类名.class
Class<Person> classTwo = Person.class;
System.out.println(classTwo);
//3、对象.getClass();
Class<? extends Person> classThree = new Person().getClass();
System.out.println(classThree);
}
}
2.2 获取类的构造方法
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name) {
this.name = name;
}
protected Person(int age) {
this.age = age;
}
private Person(String name, int age) {
this.name = name;
this.age = age;
}
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 +
'}';
}
}
public class Demo02_1 {
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, InvocationTargetException,
InstantiationException, IllegalAccessException {
//1、获取class字节码文件对象
Class<?> clazz = Class.forName("com.hu.demo02.Person");
//2、获取public修饰的构造方法
Constructor<?>[] cons1 = clazz.getConstructors();
/* for (Constructor con : cons1) {
System.out.println(con);
}*/
//3、获取所有的构造方法
Constructor<?>[] cons2 = clazz.getDeclaredConstructors();
/*for (Constructor con : cons2) {
System.out.println(con);
}*/
//获取单个构造方法
Constructor<?> con3 = clazz.getDeclaredConstructor(String.class,int.class);
System.out.println(con3);
con3.setAccessible(true);
//利用有参构造生成对象
Person person = (Person) con3.newInstance("小明", 12);
System.out.println(person);
}
}
2.3 获取类的成员变量
public class Person {
private String name;
private int age;
public String gender;
public Person() {
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
public class Demo02_1 {
public static void main(String[] args) throws ClassNotFoundException,
NoSuchFieldException, IllegalAccessException {
//1、获取class字节码文件对象
Class<?> clazz = Class.forName("com.hu.demo02.Person");
//2、获取成员变量
/**
* getFields 只能获取public修饰的
* getDeclaredFields 获取所有的
*/
Field[] fields = clazz.getDeclaredFields();
/*for (Field field : fields) {
System.out.println(field);
}*/
//3、获取单个成员变量
/**
* getField 只能获取public修饰的
* getDeclaredField 都能获取
*/
Field name = clazz.getDeclaredField("name");
System.out.println(name);
//4、获取权限修饰符
int modifiers = name.getModifiers();
System.out.println(modifiers);
//5、获取成员变量的值
Person person = new Person("小白", 20, "男");
name.setAccessible(true);
String name1 = (String) name.get(person);
System.out.println(name1);
//6、修改成员变量的值
name.set(person,"大白");
System.out.println(person);
}
}
2.4 获取类的成员方法
public class Person {
private String name;
private int age;
public String gender;
public Person() {
}
public Person(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public void sleep() {
System.out.println("在睡觉");
}
private void eat(String something) {
System.out.println("在吃什么" + something);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
public class Demo02_1 {
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, InvocationTargetException,
IllegalAccessException {
//1、获取class字节码文件对象
Class<?> clazz = Class.forName("com.hu.demo02.Person");
//2、获取所有的方法对象,包括父类中所有的公共方法
Method[] methods = clazz.getMethods();
/*for (Method method : methods) {
System.out.println(method);
}*/
//3、获取所有的方法对象,不包括父类中的方法。
Method[] declaredMethods = clazz.getDeclaredMethods();
/* for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}*/
//4、获取单个方法
Method eat = clazz.getDeclaredMethod("eat", String.class);
System.out.println(eat);
Person person = new Person();
eat.setAccessible(true);
eat.invoke(person,"馒头");
}
}
3、动态代理
特点:无侵入式的给代码增加额外的功能
1.为什么需要代理?
代理可以无侵入式的给对象增强其他的功能
调用者-->代理-->对象
2.代理长什么样?
代理里面就是对象要被代理的方法
3、Java通过什么来保证代理的样子?
通过接口保证,后面的对象和代理需要实现同一个接口
接口中就是被代理的所有方法
3.1 如何为Java对象创建一个代理对象
java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法
newProxyInstance方法
参数一:用于指定用哪个类加载器,去加载生成的代理类
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
参数三:用来指定生成的代理对象要干什么事情
public class BigStar implements Star{
private String name;
public BigStar() {
}
public BigStar(String name) {
this.name = name;
}
//唱歌
@Override
public String sing(String name) {
System.out.println(this.name + "正在唱" + name);
return "谢谢";
}
//跳舞
@Override
public void dance() {
System.out.println(this.name + "正在跳舞");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "BigStar{" +
"name='" + name + '\'' +
'}';
}
}
/**
* 想要被代理的方法写在接口里
*/
public interface Star {
//唱歌
public abstract String sing(String name);
//跳舞
public abstract void dance();
}
/**
* 创建一个代理
*/
public class ProxyUtil {
/**
* @param bigStar 被代理的对象
* @return 给明星创建的代理
*/
public static Star createProxy(BigStar bigStar) {
/**
* 参数一:用于指定用哪个类加载器,去加载生成的代理类
* 参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
* 参数三:用来指定生成的代理对象要干什么事情
*/
Star star = (Star) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
new Class[]{Star.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 参数一: 代理对象
* 参数二: 要运行的方法
* 参数三: 调用方法是,传递的实参
*/
if ("sing".equals(method.getName())) {
System.out.println("准备话筒,收钱!");
} else if ("dance".equals(method.getName())) {
System.out.println("准备场地,收钱!");
}
return method.invoke(bigStar, args);
}
}
);
return star;
}
}
public class Test {
public static void main(String[] args) {
//获取代理对象
BigStar bigStar = new BigStar("鸡哥");
Star proxy = ProxyUtil.createProxy(bigStar);
//调用代理方法
String result = proxy.sing("鸡你太美");
System.out.println(result);
proxy.dance();
}
}
时间:2023-06-26 下午

浙公网安备 33010602011771号