EchoDemo's Blogs

Java反射API(一)

1、Java.lang.reflect库

Class类和java.lang.reflect类库一起对反射的概念进行支持。在java.lang包下:Class:表示一个正在运行的Java应用程序中的类和接口,是Reflection的起源。在java.lang.reflect包下:Field类:代表类的成员变量(也称之为类的属性);Method类:代表类的方法;Constructor类:代表类的构造方法;Array类:提供动态创建数组,以及访问数组的元素的静态方法。

2、通过反射实例化对象

(1)平常情况我们通过new Object来生成一个类的实例,但有时候我们没法直接new,只能通过反射动态生成。

(2)实例化无参构造函数的对象,两种方式:

Class.newInstace();

Class.getConstructor(new Class[]{}).newInstance(new Object[]{});

(3)实例化带参构造函数的对象

Class.getConstructor(Class<?>...parameterTypes).newInstance(Object...initargs);

3、通过反射获取并调用方法

(1)获得当前类以及超类的public Method

Method[] arrMethods=classType.getMethods();

(2)获得当前类申明的所有Method

Method[] arrMethods=classTyep.getDeclaredMethods();

(3)获得当前类以及超类指定的public Method

Method method=classType.getMethod(String name,Class<?>...parameterTypes);

(4)获得当前类申明的指定的Method

Method method=classType.getDeclaredMethod(String name,Class<?>...parameterTypes);

(5)通过反射动态运行指定Method

Object  obj=method.invoke(Object obj,Object...args);

4、通过反射获取并调用属性

(1)获得当前类以及超类的public Field

Field[] arrFields=classType.getFields();

(2)获得当前类申明的所有Field

Field[] arrFields=classType.getDeclaredFields();

(3)获得当前类以及超类指定的public Field

Field field=classType.getField(String name);

(4)获得当前类申明的指定的Field

Field field=classType.getDeclaredField(String name);

(5)通过反射动态设定Field的值

field.set(Object obj,Object value);

(6)通过反射动态获取Field的值

Object obj=field.get(Object obj);

5、举例

package com.iotek.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionAPIDemo {

    public static void main(String[] args) throws Exception{
        /**
         * 只要用到反射,先获得Class对象。没有方法能够获得当前类的超类的private方法和属性,
         * 你必须通过getSuperclass()找到超类以后再去尝试获得。通常情况下,即使是当前类,
         * private属性或者方法也是不能访问的,你需要设置压制权限setAccessible(true)来
         * 取得private的访问权。但这样的话,就破坏了面向对象的规则,所以除非万不得已,尽量少用。
         */

        //获取Emploee这个类所关联的class对象
        Class<?> classType=Class.forName("com.iotek.reflect.Emploee");
        //通过反射机制来构造一个Emploee的实例对象(默认调用无参的构造方法)
        Emploee emploee=(Emploee)classType.newInstance();
        //调用指定的构造方法来实例化对象
        Constructor<?> constructor=classType.getConstructor(new Class[]{});
        Emploee emploee2=(Emploee)constructor.newInstance(new Object[]{});
        System.out.println(emploee);
        System.out.println(emploee2);
        //调用指定的构造方法来实例化对象(调用带参数的构造方法)
        Constructor<?> constructor1=classType.getConstructor(new Class[]{String.class,int.class});
        Emploee emploee3=(Emploee)constructor1.newInstance(new Object[]{"zhangsan",30});
        System.out.println(emploee3);

        //获取class对象指定的方法,包括私有的
        Method method=classType.getDeclaredMethod("toString", new Class[]{});
        System.out.println(method.getName());
        //方法的调用
        String desc=(String) method.invoke(emploee, new Object[]{});
        System.out.println(desc);

        //获取class对象指定的所有方法,包括私有的(私有的是默认不能被访问的)
        Method[] methods = classType.getDeclaredMethods();
        for(Method method2 : methods){
            method2.setAccessible(true);//私有的可以访问了
            System.out.println(method2.getName()+"-->"+method2.getModifiers());
        }

        //获取Class对象所指定的属性,包括私有的(私有的默认是不能被访问的)
        Field field = classType.getDeclaredField("nameString");
        field.setAccessible(true);//可访问了
        field.set(emploee, "李四");
        System.out.println(field.get(emploee));
    }
}

class Emploee{
    private String nameString;
    private int age;

    public Emploee(){
        System.out.println("无参构造法方法");
    }
    public Emploee(String nameString, int age) {
        super();
        this.nameString = nameString;
        this.age = age;
    }
    public String getNameString() {
        return nameString;
    }
    public void setNameString(String nameString) {
        this.nameString = nameString;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Emploee [nameString=" + nameString + ", age=" + age + "]";
    }
}

6、使用反射机制来创建一维数组和二维数组

package com.iotek.reflect;

import java.lang.reflect.Array;

public class ReflectionArrayDemo {

    public static void main(String[] args) throws ClassNotFoundException {
        //创建一个一维数组(String)
        Class<?> classType = Class.forName("java.lang.String");
        Object obj = Array.newInstance(classType,5);
        Array.set(obj, 3, "abc");
        System.out.println(Array.get(obj, 3));

        //创建二维数组(3行3列)
        int[] dimens={3,3};
        Object obj1 = Array.newInstance(int.class, dimens);
        Object obj2 = Array.get(obj1, 2);//获取第三行(它是一个一维数组)
        Array.setInt(obj2, 2, 5);//给指定位置赋值
        int[][] obj3 = (int[][])obj1;
        System.out.println(obj3[2][2]);
    }
}
🐶 您的支持将鼓励我继续创作 🐶
-------------本文结束感谢您的阅读-------------