java反射基础总结(未完待续)

能够分析类能力的程序称为反射。反射库提供的工具集能够编写动态操纵Java代码的程序。这项技术被大量应用于JAVABEAN中。反射可以用来在运行时分析类的能力,在运行时查看对象,实现通用的数组操作代码。

CLASS类

在程序运行期间,java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。

如何获取一个CLASS对象

1 任意的JAVA类型调用class属性

public class Reflect {
    public static void main(String[] args) {
        System.out.println(Reflect.class);
    }
}

注意,基本类型也有该属性

 

 

 

 

 

2 CLASS类中的静态方法forName

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        String s = "java.util.Random";
        Class aClass = Class.forName(s);
        System.out.println(aClass.getName());
    }
}

 

 

 注意,forName方法会抛出一个已检查异常,需要提供一个异常处理器

3 Object类中的getClass()方法将会返回一个CLASS类型的实例

public class Reflect {
    public static void main(String[] args) {
        String s = "";
        System.out.println(s.getClass());
    }
}

 

 

 结果会打印出类的全限定名(带有包名)

通过class类动态创建新对象

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        String s = "java.util.Random";
        Class aClass = Class.forName(s);
        System.out.println(aClass.getName());
        Object instance = aClass.newInstance();
        System.out.println(instance);
    }
}

 

 

 该方法会调用类的默认构造器(即无参构造器),如果没有默认构造器,就会抛出异常,如果想调用指定的构造器创建新对象,需要使用Constructor类中的newInstace方法

 

利用反射分析类的能力

通过class对象,可以获得该类的相关信息,包括属性,方法,构造器等

在反射包中有三个类Field,Method,Constructor分别用于描述类的域、方法和构造器。

1 构造器

   getDeclaredConstructors();    获取所有的构造函数

   getDeclaredConstructor(参数类型);  获取一个构造函数

   getConstructors();          获取所有公开(public)的构造函数

   getConstructor(参数类型);        获取单个公开的构造函数

//获取所有的构造函数
        Constructor[] constructors = clz.getDeclaredConstructors();
        //获取单个所有的构造函数
        try {
            Constructor constructor =               
            clz.getDeclaredConstructor(String.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        //获取所有的公开构造函数
        Constructor[] constructors1 = clz.getConstructors();
        //获取单个公开构造函数
        try {
            Constructor constructor = clz.getConstructor(String.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

2 Method

与上面类似

getMethods   返回所有公共的方法,包括父类继承的公共方法

getDeclareMethods 返回所有的方法,但不包括继承的方法(如果继承方法在子类中实现,就可以获得到) 

getMethod(String name, Class… parameterTypes)  返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法(不包括私有,但可以获得父类中未被继承的方法)。 

getDeclaredMethod(String name, Class… parameterTypes)   返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法(可以获取私有)。

3 Field

不写了,把上面method换成field就行了,类似的。

4 修饰符

使用Class对象可以获取一个类的修饰符.类的修饰符即关键字"public","private", "static"等. 如下:

    Class aClass = MyObject.class;
    int modifiers = aClass.getModifiers();

修饰符被包装进一个int内,每一个修饰符都是一个标志位(置位或清零)。可以使用java.lang.reflect.Modifier中的以下方法来检验修饰符:

    Modifier.isAbstract(int modifiers)
    Modifier.isFinal(int modifiers)
    Modifier.isInterface(int modifiers)
    Modifier.isNative(int modifiers)
    Modifier.isPrivate(int modifiers)
    Modifier.isProtected(int modifiers)
    Modifier.isPublic(int modifiers)
    Modifier.isStatic(int modifiers)
    Modifier.isStrict(int modifiers)
    Modifier.isSynchronized(int modifiers)
    Modifier.isTransient(int modifiers)
    Modifier.isVolatile(int modifiers)

5 包信息

getPackage(): 从Package对象中你可以访问诸如名字等包信息

其它(太多了,写不动了)

这篇博客讲的挺详细的

在运行时使用反射分析对象

访问私有方法,属性

反射中获取私有方法或者属性需要用setAccessible方法获取权限,setAccessible方法时AccessibleObject类中的一个方法,它是Field,Method和Constructor类的公共超类。

import java.lang.reflect.Field;
import java.util.Arrays;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        People people = new People("laowang", 18);
        Class aClass = people.getClass();
        Field[] fields = aClass.getDeclaredFields();
        System.out.println(Arrays.toString(fields));

        Field publicField = aClass.getDeclaredField("name"); //name是public
        Object o = publicField.get(people);
        System.out.println(o);

        Field privateField = aClass.getDeclaredField("age");  //age是private
        Object o1 = privateField.get(people);
        System.out.println(o1);
    }
}

 

 获取age抛出异常

 

 

使用反射编写泛型数组代码

调用任意方法

 

posted @ 2020-12-19 16:49  二仙桥下摸鱼  阅读(111)  评论(0)    收藏  举报