Java通过反射来操作类的结构信息、创建对象、访问类的成员。

Java学习-12-韩顺平老师

Java-反射机制02

目录:

01-通过反射获取类的结构信息
02-通过反射创建对象
03-通过反射访问类的成员

01-通过反射获取类的结构信息

java.lang.Class:

1.getName:获取全类名
2.getSimpleName:获取简单类名
3.getFields:获取所有public修饰的属性,包含本类以及父类的
4.getDeclaredFields:获取本类中所有属性
5.getMethods:获取所有public修饰的方法,包含本类以及父类的
6.getDeclaredMethods:获取本类中所有方法
7.getConstructors:获取所有public修饰的构造器,包含本类以及父类的
8.getDeclaredConstructors;获取本类中所有构造器
9.getPackage:以Package形式返回 包信息
10.getSuperClass:以Class形式返回父类信息
11.getlnterfaces:l以Classl1形式返回接口信息
12.getAnnotations:以Annotationl 形式返回注解信息

public class Class_ {
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> cls = Class.forName("com.zcc.class_.Animal");
        // getName
        System.out.println(cls.getName()); // com.zcc.class_.Animal
        // getSimpleName
        System.out.println(cls.getSimpleName()); // Animal
        // getFields 输出如下
        // public int com.zcc.class_.Animal.num1
        // public int com.zcc.class_.A.i1
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        // getDeclaredFields 输出以下
        /*
            public int com.zcc.class_.Animal.num1
            1
            int
            num1
            protected int com.zcc.class_.Animal.num2
            4
            int
            num2
            int com.zcc.class_.Animal.num3
            0
            int
            num3
            private int com.zcc.class_.Animal.num4
            2
            int
            num4
        */
        Field[] declaredFields = cls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
            System.out.println(declaredField.getModifiers());
            System.out.println(declaredField.getType());
            System.out.println(declaredField.getName());
        }
        // 以下两个与上述两个一致
        // cls.getMethods() / cls.getDeclaredMethods()
        // cls.getConstructors() / cls.getDeclaredConstructors()

        // getPackage
        System.out.println(cls.getPackage()); // package com.zcc.class_
        // getInterfaces
        System.out.println(cls.getInterfaces().length); // 1
        // getAnnotations
        System.out.println(cls.getAnnotations().length); // 1
    }
}

class A{
    public int i1 =10;
    public void s1(){}
}
interface IA{}
@Deprecated
class Animal extends A implements IA{
    public int num1 = 10;
    protected int num2 =20;
    int num3 =30;
    private int num4 =40;
    public Animal(){

    }
    public Animal(int num1){
        num1 =num1;
    }

    public void m1(){}
    protected void m2(){}
    void m3(){}
    private void m4(){}
}

java.lang.reflect.Constructor:

1.getModifiers:以int形式返回修饰符
2.getName:返回构造器名(全类名)
3.getParameterTypes:以Class[]返回参数类型数组
演示代码写在上面

java.lang.reflect.Field:

1.getModifiers:以int形式返回修饰符
[说明:默认修饰符 是0,public #1, private # 2, protected # 4,
static是8,final是 16]
2.getType:lClass形式返回类型
3.getName:返回属性名
演示代码写在上面

java.lang.reflect.Method:

1.getModifiers:l以int形式返回修饰符
[说明:默认修饰符 是0,
public #1, private # 2, protected # 4,
static是8,final是 16]
2.getReturnType:lClass形式获取 返回类型
3.getName:返回方法名
4.getParameterTypes:l以Class1返回参数类型数组
演示代码写在上方

02-通过反射创建对象

1.方式一:调用类中的public修饰的无参构造器
2.方式二:调用类中的指定构造器
3.Class类相关方法
newlnstance:调用类中的无参构造器,获取对应类的对象
getConstructor(Class…clazz):根据参数列表,获取对应的public构造器对象
getDecalaredConstructor(ClasS…clazz):根据参数列表,获取对应的所有构造器
对象,主要用来获取私有的,里面填入对应的参数Class对象,会自动匹配构造器。
4.Constructor类相关方法
setAccessible:爆破
newlnstance(Object…obj):调用构造器

public class CreateObjectByClass {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        // Class
        Class<?> cls = Class.forName("com.zcc.class_.Person");
        // 通过newInstance获得 实例对象
        Person p = (Person)cls.newInstance();

        // 使用构造器
        Constructor<?> constructor = cls.getConstructor();
        Person p1 =(Person) constructor.newInstance();
        // 使用有参构造器, 在后面填入参数列表对应的Class对象,会自动匹配构造器
        Constructor<?> declaredConstructor = cls.getDeclaredConstructor(String.class, int.class);
        // 因为是私有的构造器,所以采取爆破的方式访问
        declaredConstructor.setAccessible(true);
        Person p2 = (Person)declaredConstructor.newInstance("张三", 19);
        System.out.println(p);
        System.out.println(p1);
        System.out.println(p2);
        /* 输出
            Person{name='王五', age=13}
            Person{name='王五', age=13}
            Person{name='张三', age=19}
        */
    }
}
class Person{
    private String name ="王五";
    private int age = 13;
    // 默认构造器
    public Person(){}
    // 私有有参构造器
    private Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

03-通过反射访问类的成员

访问属性:

1.根据方法名和参数列表获取Method方法对象:Method m =
clazz.getDeclaredMethod(方法名,xx.class);//得到本类的所有方法
2.获取对象:Object o=clazz.newlnstance();
3.暴破:m.setAccessible(true);
4.访问:Object returnValue=m.invoke (0,实参列表);
5.注意:如果是静态方法,则invoke的参数。,可以写成null!

访问方法:

1.根据属性名获取Field对象
Field f=clazz对象.getDeclaredField(属性名);
2.暴破:f.setAccessible(true);1/f是Field
3.访问
f.set(o,值);
syso(f.get(o));
4.如果是静态属性,则set和get中的参数o,可以写成null

代码演示:

public class Visit {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<?> cls = Class.forName("com.zcc.class_.Person");
        Object o = cls.newInstance();
        // getField获取的共有属性
        Field field = cls.getField("age");
        // 访问共有属性
        System.out.println(field.get(o)); // 18
        System.out.println(field.get(null)); // 18
        // 获取私有属性
        Field name = cls.getDeclaredField("name");
        // 访问私有属性必须使用setAccessible爆破
        name.setAccessible(true);
        System.out.println(name.get(o));// 张三

        // 获取公开方法
        Method getAge = cls.getMethod("getAge");
        System.out.println(getAge.invoke(o)); // 18
        System.out.println(getAge.invoke(null)); // 18
        // 获取私有方法
        Method declaredMethod = cls.getDeclaredMethod("getName");
        // 私有方法必须爆破才能访问
        declaredMethod.setAccessible(true);
        System.out.println(declaredMethod.invoke(o));
    }
}

class Person{
    // 私有属性
    private String name = "张三";
    // 公开静态属性
    public static int age = 18;

    // 共有方法
    public static int getAge(){
        return age;
    }
    // 私有方法
    private String getName(){
        return this.name;
    }
}

反射机制小结,欢迎大家交流学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值