Java反射的使用

一、什么是反射

  • 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的 方法的功能就称为java语言的反射机制。

 二、反射的主要用途

 反射是框架设计的灵魂

三、反射框架提供的功能

  • 判断任意一个对象所属的类;
  • 构造任意一个类的对象;
  • 判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
  • 调用任意一个对象的方法

 四、反射的运用

1. 获得Class对象(3种方式)

1.使用Class类的forName静态方法
Class<?> aClass1 = Class.forName("类的全路径");

2.调用某个对象的getClass()获得
User user = new User();
Class<? extends User> aClass2 = user.getClass();

3.通过某一个对象获得
Class<User> aClass3 = User.class;

2. 创建实例(2种方式)

1. 通过使用Class对象的newInstance()方法创建实例
Object o1 = aClass1.newInstance();

2. 先获取构造器,通过构造器创建实例
Constructor<?> constructor1 = aClass1.getConstructor();
Object o2 = constructor1.newInstance();

注:
    aClass1.getConstructor(Class<?>... parameterTypes)可指定不同参数构造方法
如:
    //获取参数为String构造器实例
    Constructor<?> constructor1 = aClass1.getConstructor(String.class);
    Object o2 = constructor1.newInstance("你好呀");
    
    或
    
    //获取参数类型为int的构造器实例
    Constructor<?> constructorInt1 = aClass1.getConstructor(int.class);
    Object o3 = constructorInt1.newInstance(18);

3. 判断是否为某个类的实例(用于检查给定对象是否是具有此Class表示的对象的实例)

boolean instance = aClass1.isInstance(o2);		//结果为  true

boolean instance = aClass1.isInstance("abc");	//结果为  false

4. 获取类的方法

1. 获取方法返回类或接口声明的所有方法,包括公共,受保护,默认,私有方法,不包括继承方法
Method[] declaredMethods = aClass1.getDeclaredMethods();

2. 获取所有公有方法(public),包括继承公用方法
Method[] methods = aClass1.getMethods();

3. 获取指定的方法,第一个参数为方法名,第二个为参数类型
Method getUserName = aClass1.getDeclaredMethod("getUserName", String.class);

4. 获取指定的方法,第一个参数为方法名,第二个为参数类型
Method getUserAge = aClass1.getMethod("getUserAge", int.class);

5. 方法的调用

//第一个参数为调用底层方法的对象,第二个参数为调用方法的参数
Object invoke = getUserName.invoke(o1,"哇呀呀呀");

System.out.println(invoke);//结果为 name:哇呀呀呀

6. 获取类的成员变量

1. 获取公有的成员变量
Field[] fields = aClass1.getFields();

2. 获取所有已声明的成员变量,不能得到父类的成员变量
Field[] declaredFields = aClass1.getDeclaredFields();

3. 获取公有成员变量,指定属性名
Field phone = aClass1.getField("phone");

4. 获取所有已声明的成员变量,指定属性名
Field name = aClass1.getDeclaredField("name");

7. 设置属性值

//获取公有成员变量,指定属性名
Field phone = aClass1.getField("phone");

phone.set(o1,"123456789");

//获取所有已声明的成员变量,指定属性名
Field name = aClass1.getDeclaredField("name");

//当属性为私有时,要设置此属性为true,否则会报错哦
name.setAccessible(true);

name.set(o1,"小小的愿望");

System.out.println(obj);	//结果为 User(name=小小的愿望, age=0, phone=123456789)

五、反射的注意事项

  • 反射比较消耗性能,所以避免在经常执行的代码中使用反射。
  • 反射要求在没有安全限制的环境中运行,如果一个程序对安全性提出要求,最好不要使用反射。
  • 反射允许代码执行一些通常不被允许的操作,所以使用反射有可能导致意想不到的后果。反射代码破坏了Java程序结构的抽象性,所以当程序运行的平台发生变化时,由于抽象的逻辑结构不能被识别,代码产生的效果与之前会产生差异。

六、 User类

package com.yf.business.Test;
import lombok.Data;

@Data
public class User {

    private String name;
    private int age;
    public String phone;

    public String getUserName(String name){
        return "name:"+name;
    }

    public String getUserAge(int age){
        return "age:"+age;
    }

    private String getUser(String name, int age){
        return "name:"+name+",age:"+age;
    }
    
    //全参构造
    public User(String name, int age,String phone) {
        this.name = name;
        this.age = age;
        this.phone = phone;
    }

    public User(String name){
        this.name = name;
        this.age = 8;
    }

    public User(int age){
        this.name = "hello";
        this.age = age;
    }
    
    //无参构造
    public User(){
    }
}

Java反射可以让我们在运行时获取和操作类的信息,包括类的属性、方法、构造函数等。下面是一个使用Java反射的简单案例: 假设我们有一个类Person: ```java public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public void sayHello() { System.out.println("Hello, my name is " + name + ", I am " + age + " years old."); } } ``` 现在,我们可以使用反射来获取和调用Person类的构造函数和方法: ```java import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class ReflectionExample { public static void main(String[] args) throws Exception { // 获取Person类的Class对象 Class<Person> personClass = Person.class; // 获取Person类的构造函数 Constructor<Person> constructor = personClass.getConstructor(String.class, int.class); // 使用构造函数创建Person对象 Person person = constructor.newInstance("Tom", 20); // 获取Person类的sayHello方法 Method sayHelloMethod = personClass.getMethod("sayHello"); // 调用sayHello方法 sayHelloMethod.invoke(person); } } ``` 以上代码中,我们首先通过`Person.class`获取了Person类的Class对象,然后使用`getConstructor`方法获取了Person类的构造函数,并使用构造函数创建了一个Person对象。接着,我们使用`getMethod`方法获取了Person类的`sayHello`方法,并使用`invoke`方法调用了该方法。最终,我们输出了`Hello, my name is Tom, I am 20 years old.`。 这只是一个简单的反射案例,实际上Java反射还可以做很多其他的事情,比如动态代理、注解处理等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值