第一节 反射(高级)

前言

反射是Java程序开发语言的特征之一,它允许运行中的Java程序对自身进行检查,或者说进行”自省”。

基本应用

通过反射获取类的实例

package com.njlife123.qzmall.base;

public class Q {
    int a = 2;
    int b = 2;

    public Q() {
    }

    public Q(int a) {
        this.a = a;
    }

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }
}

package com.njlife123.qzmall.base;

public class Test5 {
    
    public static void main(String[] args) throws Exception {
        //包名.类名 
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
        //强转成Q类
        Q q = (Q)aClass.newInstance();
        
    }
}

获取类属性信息

package com.njlife123.qzmall.base;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test5 {

    public static void main(String[] args) throws Exception {
        //包名.类名
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
        Field[] fields = aClass.getDeclaredFields();//获取属性信息
        for (int i=0;i<fields.length;i++){
            Field field = fields[i];
            //判断是否是私有
            if(field.isAccessible()){
                field.setAccessible(false);
            }

            System.out.println("属性名: "+ field.getName());
            System.out.println("属性类型: "+ field.getType());
            System.out.println("属性值: "+ field.get(aClass.newInstance()));
            System.out.println("访问修饰符: "+ Modifier.toString(field.getModifiers()));
        }
    }
}

打印结果:

属性名: a
属性类型: int
属性值: 2
访问修饰符: 
属性名: b
属性类型: int
属性值: 2
访问修饰符: 

Process finished with exit code 0

获得类的方法信息

package com.njlife123.qzmall.base;

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

public class Test5 {

    public static void main(String[] args) throws Exception {
        //包名.类名
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method method : declaredMethods){
            System.out.println("方法名: "+ method.getName());
            System.out.println("返回类型: "+method.getReturnType());
            System.out.println("访问修饰符: "+ Modifier.toString(method.getModifiers()));
            //参数类型class数组
            Class<?>[] parameterTypes = method.getParameterTypes();
            if(parameterTypes.length > 0){
                for (Class c : parameterTypes){
                    System.out.print(c);
                }
            }
            System.out.println();
        }
    }
}

打印结果:

方法名: getA
返回类型: int
访问修饰符: public

方法名: setA
返回类型: void
访问修饰符: public
int

Process finished with exit code 0

获得类的构造函数信息

package com.njlife123.qzmall.base;

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

public class Test5 {

    public static void main(String[] args) throws Exception {
        //包名.类名
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");

        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor c : constructors){
            System.out.println("名字:"+c.getName());
            System.out.println("访问修饰符:"+ Modifier.toString(c.getModifiers()));
            //获取参数类型class数组
            Class[] parameterTypes = c.getParameterTypes();
            if(parameterTypes.length > 0){
                for (Class clz : parameterTypes){
                    System.out.println(clz);
                }
            }
            System.out.println();

        }
    }
}

打印结果:

名字:com.njlife123.qzmall.base.Q
访问修饰符:public

名字:com.njlife123.qzmall.base.Q
访问修饰符:public
int


Process finished with exit code 0

修改类的属性

package com.njlife123.qzmall.base;

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

public class Test5 {

    public static void main(String[] args) throws Exception {
        //包名.类名
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
        //getField只获取public修饰属性
        Field a = aClass.getField("a");
        Q q = (Q)aClass.newInstance();
        a.set(q,33);
        System.out.println(q.a);
    }
}

打印结果:

33

Process finished with exit code 0

调用类的方法

package com.njlife123.qzmall.base;

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

public class Test5 {

    public static void main(String[] args) throws Exception {
        //包名.类名
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
        Q q = (Q)aClass.newInstance();
        Method setA = aClass.getDeclaredMethod("setA", int.class);//setA参数int
        Method getA = aClass.getDeclaredMethod("getA", null);//无参数null
        setA.invoke(q,123);
        getA.invoke(q);
    }
}

Q类:

public int getA() {
        System.out.println("getA");
        return a;
    }

    public void setA(int a) {
        System.out.println("setA");
        this.a = a;
    }

调用类的构造函数

package com.njlife123.qzmall.base;

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

public class Test5 {

    public static void main(String[] args) throws Exception {
        //包名.类名
        Class<?> aClass = Class.forName("com.njlife123.qzmall.base.Q");
        //空参构造
        Constructor<?> constructor = aClass.getConstructor();
        //有参数构造 传参Class<?>... parameterTypes ,三点表示传参是数组
        Class [] c = {int.class};
        Constructor<?> constructor1 = aClass.getConstructor(c);
        //也可以这样写,比如构造器参数为int和String
       // aClass.getConstructor(int.class,String.class);
        Q q = (Q)constructor.newInstance();
        Q q1 = (Q)constructor1.newInstance(22);
        System.out.println(q);
        System.out.println(q1);
    }
}

打印结果:

空参构造
参数int a构造
com.njlife123.qzmall.base.Q@2f2c9b19
com.njlife123.qzmall.base.Q@31befd9f

Process finished with exit code 0

作者简介:一个有故事的程序员,我的微信号qiushuzhao222,欢迎大家找我聊天,记录你我的故事。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值