Java之反射(reflect)示例简介说明

乔欣 Java经验 发布时间:2022-11-24 22:13:56 阅读数:14052 1
下文笔者通过示例的方式,讲述反射(reflect)的用法,如下所示

反射(reflect)示例

反射的功能:
    用于获取字节码(Class对象)
	对于任意类,我们都可以使用反射获取类的所有属性和方法
	并且可以运行其中的方法和获取属性 

注意事项:
    反射是在java运行时
	动态获取类相关信息

获取Java反射类信息的方法

1.使用Class类的静态方法forName
    Class.forName("java.lang.String");
2.使用类的.class语法
    String.class;
3.使用对象的getClass()方法
    String str = "java265";
    Class<?> strClass = str.getClass();
例:
import java.lang.reflect.Method;
public class TestClass {
    public static void main(String[] args) throws Exception {
        // 方式一
        // Class<?> classType = Class.forName("java.lang.String");
        // 方式二
        // Class<?> classType = String.class;
        // 方式三
        String str = "java265";
        Class<?> classType = str.getClass();
        Method[] methods = classType.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }
}
------运行以上代码,将输出以下信息-----
...
public java.lang.String java.lang.String.toUpperCase(java.util.Locale)
public java.lang.String java.lang.String.trim()

反射获取类信息

  下文笔者讲述使用反射获取类信息的方法分享
  如下所示

  1.使用反射机制获取类的构造函数
        然后使用构造函数创建类的实例

    使用类的不带参数的构造方法来生成对象
    有以下两种方式
     1.1 先获得Class对象
        然后通过该Class对象的newInstance()方法
		  直接生成即可
    Class<?> classType = String.class;
    Object obj = classType.newInstance();
    
	1.2:先获得Class对象
         然后通过该对象获得对应的Constructor对象
         再通过该Constructor对象的newInstance()方法生成类对象

    Class<?> classType = Customer.class;
    Constructor cons = classType.getConstructor(newClass[]{});
    Object obj = cons.newInstance(newObject[]{});
  
  
    如果使用类的带参数的构造方法生成对象,可使用下面的方式
    Class<?> classType = Customer.class;
    Constructor cons = classType.getConstructor(newClass[]{String.class,int.class});
    Object obj = cons.newInstance(newObject[]{"java265.com",8888});

反射使用构造函数生成类对象的方法分享

import java.lang.reflect.Constructor;
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("reflex.Person");
        Constructor<Person> constructor1 = clazz.getConstructor();
        Constructor<Person> constructor2 = clazz.getConstructor(String.class);
        // 无参方式一
        Person person11 = (Person) clazz.newInstance();
        // 无参方式二
        Person person12 = constructor1.newInstance();
        // 有参方式
        Person person2 = constructor2.newInstance("java265");
    }
}

class Person {
    public Person() {
        System.out.println("我是奥特曼");
    }
    public Person(String name) {
        System.out.println("我是:" + name);
    }
}
------运行以上代码,将输出以下信息-----
我是奥特曼
我是奥特曼
我是:java265

使用反射机制获取类属性

1.获取class类:   Class<?> classType = InvokeTester.class;
2.实例化:        Object invokeTester = classType.newInstance();
3.获取field
   public字段:    Field publicField = clazz.getField("age");
   private字段:   Field privateField = clazz.getDeclaredField("name");
4.赋值:
   public字段:    publicField.set(person, 20);
   private字段:   privateField.setAccessible(true); // 对私有字段的访问取消检查
                   privateField.set(person, "tony");
5.获取值:          privateField.get(person)
例:
import java.lang.reflect.Field;
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("reflex.Person");
        Person person = (Person) clazz.newInstance();
        // public字段
        Field publicField = clazz.getField("age");
        publicField.set(person, 18);
        System.out.println(publicField.get(person));
        // private字段
        // Field privateField = clazz.getField("name"); //java.lang.NoSuchFieldException
        Field privateField = clazz.getDeclaredField("name");
        privateField.setAccessible(true); // 对私有字段的访问取消检查
        privateField.set(person, "tony");
        System.out.println(privateField.get(person));
        
    }
}
class Person {
    public int age;
    private String name;
    public Person() {
        System.out.println("我是奥特曼");
    }
    public Person(String name) {
        System.out.println("我是:" + name);
    }
}

使用反射机制获取类的方法,并运行方法

实现步骤:
	1.获取class类:   Class<?> classType = InvokeTester.class;
	2.实例化:        Object invokeTester = classType.newInstance();
	3.获取方法:      Method addMethod = classType.getMethod("add", new Class[]{int.class, int.class});
	4.调用方法:      Object addResult = addMethod.invoke(invokeTester, new Object[]{1, 2});
例:
反射获取方法,并运行方法
import java.lang.reflect.Method;
public class InvokeTester{
    public int add(int param1, int param2){
        return param1 + param2;
    }
    public String echo(String message){
        return "hello: " + message;
    }
    public static void main(String[] args) throws Exception{
        Class<?> classType = InvokeTester.class;
        Object invokeTester = classType.newInstance();
        Method addMethod = classType.getMethod("add", new Class[]{int.class, int.class});
        Object addResult = addMethod.invoke(invokeTester, new Object[]{1, 2});
        System.out.println((Integer)addResult);
        Method echoMethod = classType.getMethod("echo", new Class[]{String.class});
        Object echoResult = echoMethod.invoke(invokeTester, new Object[]{"java2655"});
        System.out.println((String)echoResult);
    }
}

使用反射复制对象

import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectTester {
    // 该方法实现对Customer对象的拷贝操作
    public Object copy(Object object) throws Exception{
        Class<?> classType = object.getClass();
        Object objectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
        Field[] fields = classType.getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            String firstLetter = name.substring(0, 1).toUpperCase(); // 将属性的首字母转换为大写
            String getMethodName = "get" + firstLetter + name.substring(1);
            String setMethodName = "set" + firstLetter + name.substring(1);
            Method getMethod = classType.getMethod(getMethodName, new Class[]{});
            Method setMethod = classType.getMethod(setMethodName, new Class[]{ field.getType() });
            Object value = getMethod.invoke(object, new Object[]{});
            setMethod.invoke(objectCopy, new Object[]{ value });
        }
        return objectCopy;
    }
    public static void main(String[] args) throws Exception{
        Customer customer = new Customer("test", 20);
        customer.setId(1L);
        ReflectTester test = new ReflectTester();
        Customer customer2 = (Customer) test.copy(customer);
        System.out.println(customer2.getId() + "," + customer2.getName() + ","+ customer2.getAge());
    }
}
class Customer{
    private Long id;
    private String name;
    private int age;
    public Customer() {
    }
    public Customer(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Long getId() {return id;}
    public void setId(Long id) {this.id = id;}
    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;}
}

反射操作数组

import java.lang.reflect.Array;
public class ArrayTester1 {
    public static void main(String[] args) throws Exception{
        Class<?> classType = Class.forName("java.lang.String");
        Object array = Array.newInstance(classType, 10);
        Array.set(array, 88, "java265");
        String str = (String)Array.get(array,88);
        System.out.println(str);
    }
}

反射运行对象的私有方法

public class Private{
    private String testFun(String name){
        return "hello: " + name;
    }
}
import java.lang.reflect.Method;
public class TestPrivate{
    public static void main(String[] args) throws Exception{
        Private p = new Private();
        Class<?> classType = p.getClass();
        Method method = classType.getDeclaredMethod("testFun",
                new Class[] { String.class });
        method.setAccessible(true);//设置Java的访问控制检查
        String str = (String)method.invoke(p, new Object[]{"java265"});
        System.out.println(str);
    }
}

反射调用对象的get方法

public class Private2{
    private String name = "java265";
    public String getName(){
        return name;
    }
}
import java.lang.reflect.Field;
public class TestPrivate2{
    public static void main(String[] args) throws Exception{
        Private2 p = new Private2();
        Class<?> classType = p.getClass();
        Field field = classType.getDeclaredField("name");
        field.setAccessible(true);//压制Java对访问修饰符的检查
        field.set(p, "lisi");
        System.out.println(p.getName());
    }
}

获取已知class父类

public class ClassTest {
    public static void main(String[] args) {
        Class<?> classType = Child.class;
        System.out.println(classType);
        classType = classType.getSuperclass();
        System.out.println(classType);
        classType = classType.getSuperclass();
        System.out.println(classType);
        classType = classType.getSuperclass();
        System.out.println(classType);
    }
}
class Parent{}
class Child extends Parent{}
运行结果:
class com.java265.Child
class com.java265.Parent
class java.lang.Object
null
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202211/16692992844972.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者