Java中反射reflect_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java中反射reflect

Java中反射reflect

 2018/10/16 12:45:26  andrew7676  程序员俱乐部  我要评论(0)
  • 摘要:1.反射获取字节码(Class对象)Java反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为Java的反射机制。1.要想使用反射,首先需要获得待处理类或对象所对应的Class对象。获取某个类或某个对象所对应的Class对象的常用的3种方式:a)使用Class类的静态方法forNameClass.forName("java.lang.String");b)使用类的
  • 标签:Java 反射
1. 反射获取字节码(Class对象)
class="java" name="code">
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
发表评论
用户名: 匿名