`

Java中反射reflect

    博客分类:
  • Java
阅读更多
1. 反射获取字节码(Class对象)

Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。
这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。

1. 要想使用反射,首先需要获得待处理类或对象所对应的Class对象。获取某个类或某个对象所对应的Class对象的常用的3种方式:
a) 使用Class类的静态方法forName
    Class.forName("java.lang.String");
b) 使用类的.class语法
    String.class;
c) 使用对象的getClass()方法
    String str = "abc";
    Class<?> strClass = str.getClass();

import java.lang.reflect.Method;
public class DumpMethods {
    public static void main(String[] args) throws Exception {
        // 方式一
        // Class<?> classType = Class.forName("java.lang.String");
        // 方式二
        // Class<?> classType = String.class;
        // 方式三
        String str = "abc";
        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()


2. 反射获取类信息

1. 通过反射机制获取类的构造函数,通过构造函数创建类的实例。

1) 若想通过类的不带参数的构造方法来生成对象,我们有两种方式:
a) 先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:
    Class<?> classType = String.class;
    Object obj = classType.newInstance();
b) 先获得Class对象,然后通过该对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成:
    Class<?> classType = Customer.class;
    Constructor cons = classType.getConstructor(newClass[]{});
    Object obj = cons.newInstance(newObject[]{});

2) 若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:
    Class<?> classType = Customer.class;
    Constructor cons = classType.getConstructor(newClass[]{String.class,int.class});
    Object obj = cons.newInstance(newObject[]{"hello", 3});

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("andrew");
    }
}
class Person {
    public Person() {
        System.out.println("我是路人");
    }
    public Person(String name) {
        System.out.println("我是:" + name);
    }
}
运行结果:
我是路人
我是路人
我是:andrew

2. 通过反射机制获取类的属性。

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, 20);
        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);
    }
}
运行结果:
我是路人
20
tony

3. 通过反射机制获取类的方法,并调用方法。

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{
        // InvokeTester test = new InvokeTester();
        // System.out.println(test.add(1, 2));
        // System.out.println(test.echo("tom"));
        Class<?> classType = InvokeTester.class;
        Object invokeTester = classType.newInstance();
        // System.out.println(invokeTester instanceof InvokeTester);
        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[]{"tom"});
        System.out.println((String)echoResult);
    }
}
运行结果:
3
hello: tom


3. 使用反射拷贝对象

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("anderw", 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;}
}
运行结果:
1,anderw,20


4. 使用反射

数组与反射
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, 5, "hello");
        String str = (String)Array.get(array, 5);
        System.out.println(str);
    }
}
运行结果:
hello

Class对象的getComponentType()方法返回一个数组类型的对象
import java.lang.reflect.Array;
public class ArrayTester2{
    public static void main(String[] args){
        int[] dims = new int[] { 5, 10, 15 };
        Object array = Array.newInstance(Integer.TYPE, dims);
        System.out.println(array instanceof int[][][]);
        Object arrayObj = Array.get(array, 3);
        Class<?> classType = arrayObj.getClass().getComponentType();
        System.out.println(classType);
        arrayObj = Array.get(arrayObj, 5);
        Array.setInt(arrayObj, 10, 37);
        int[][][] arrayCast = (int[][][]) array;
        System.out.println(arrayCast[3][5][10]);
        System.out.println(Integer.TYPE);
        System.out.println(Integer.class);        
    }
}
运行结果:
true
class [I
37
int
class java.lang.Integer

反射调用对象的私有方法
public class Private{
    private String sayHello(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("sayHello",
                new Class[] { String.class });
        method.setAccessible(true);//压制Java的访问控制检查
        String str = (String)method.invoke(p, new Object[]{"zhangsan"});
        System.out.println(str);
    }
}
运行结果:
hello:zhangsan

反射调用对象的get方法
public class Private2{
    private String name = "zhangsan";
    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());
    }
}
运行结果:
lisi

获取已知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 org09.Child
class org09.Parent
class java.lang.Object
null


推荐博客:
https://blog.csdn.net/sinat_38259539/article/details/71799078
分享到:
评论

相关推荐

    java中的反射reflect

    Java中的反射(Reflect)是Java语言的一个重要特性,它允许运行时访问类、接口、字段和方法的信息,甚至能够在运行时动态地创建对象和调用方法。反射在很多场景下都发挥着关键作用,比如在框架开发、插件系统、序列化...

    Java中的reflect 反射的基本东西,

    Java中的反射机制是Java语言提供的一种强大的工具,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的...通过理解并熟练掌握Java反射机制,开发者可以更好地利用Java的动态性,提高代码的可扩展性和维护性。

    java反射JAVA REFLECT (java 反射)

    JAVA REFLECT (java 反射) 取得类的继承结构 - 类所在的包; |- public Package getPackage() - 类的声明方式; |-取得全类名:public String getName() |-只取类名: public String getSimpleName() - 类所继承...

    java反射(reflect)

    Java反射(Reflect)是Java语言中的一个重要特性,它允许运行时的Java程序访问、操作类、接口、字段和方法的信息,甚至动态调用方法。在Java编程中,反射提供了强大的能力,可以用来实现一些高级功能,如元编程、...

    9.3 Java反射reflect

    Java反射机制是Java编程语言中一个强大的特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具备了高度的灵活性,能够在运行时动态地获取类的信息并调用对象的方法。Java...

    java中反射的概念

    总的来说,Java反射机制是面向对象编程的一个重要补充,它扩展了Java程序的动态性,允许程序员在运行时访问和操作类的内部结构,增强了代码的灵活性。理解和熟练掌握反射技术,对于提升Java编程能力,尤其是处理复杂...

    Java方法反射调用demo

    Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有了高度的灵活性,常用于框架开发、插件系统、元编程等...

    Java EE:Reflect 反射技术.docx

    Java反射机制允许我们在程序运行期间动态地获取类、接口、字段和方法的信息,并能对这些信息进行操作。例如,我们可以获取一个对象的类类型,实例化未知类型的对象,访问和修改私有属性,以及调用任意方法。反射机制...

    Java中的反射机制Reflect

    在深入理解Java反射机制之前,我们首先需要知道什么是类的元数据,即关于类本身的信息。Java的反射机制就是通过这些元数据来操作类的实例。 在Java中,`java.lang.Class` 类是所有类的通用表示,它代表了Java运行时...

    java面试题--反射机制

    Java反射机制主要依赖于`java.lang.reflect`包下的API,其中包括: - `java.lang.Class`:表示一个类的运行时信息。 - `java.lang.reflect.Method`:表示类的方法。 - `java.lang.reflect.Field`:表示类的字段。 -...

    java 反射-(reflect)

    Java反射是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。在Java中,反射机制的核心类是`java.lang.Class`,它代表了类的信息。通过反射,我们可以动态地...

    什么是java中的反射机制(reflect).docx

    Class 类代表了 Java 中的一个类,而 java.lang.reflect 包提供了许多反射类,例如 Constructor、Method、Field 等。 Constructor 类代表了某个类中的一个构造方法。例如,我们可以使用 Class.forName("java.lang....

    Java中的反射机制

    Java反射机制允许运行中的程序检查自身,并能直接操作程序的内部属性。这是其他许多编程语言(如Pascal、C或C++)不具备的能力。 **1.1 Reflection的工作机制** 为了展示反射如何工作,我们来看一个简单的例子: ...

    Java反射性能测试分析

    Java反射机制是Java编程语言中一个强大的特性,它允许程序在运行时动态地访问、检测和修改类、接口、字段和方法等对象。然而,反射操作通常会引入额外的开销,这在性能敏感的应用场景下可能成为一个瓶颈。本文将深入...

    java中反射知识总结

    2. **类对象** - 在Java中,每个类都有一个对应的Class对象,它是Java反射的入口。我们可以通过Class对象来实例化对象、获取类的构造器、方法和字段信息。例如,`Class&lt;?&gt; clazz = Class.forName("全限定类名");` 这...

    JAVA反射机制的入门代码

    Java反射机制是Java编程语言中的一个强大特性,它允许运行中的Java程序对自身进行检查并且可以直接操作程序的内部属性。这个特性使得Java具有了高度的灵活性和动态性,尤其是在处理元数据、创建对象、调用私有方法...

    反射实例-JAVA反射机制

    在Java反射中,针对类的不同组成部分(构造函数、字段和方法),`java.lang.Class`类提供了多种反射调用方式来获取信息。以下是几种常用的反射调用: - **获取构造函数**:`Constructor getConstructor(Class[] ...

Global site tag (gtag.js) - Google Analytics