面试准备之Java反射

目录

Class类常用到的有方法有

1.获取Class对象的三种方式

2.获取类的相关属性

3.获取类的公开方法和私有方法

4.获取构造方法

5.反射的好处和坏处


在运行时通过Class对象动态获取类信息,并且可以操作类或对象的内部属性。反射可以动态创建对象并调用其属性。而这种动态获取信息以及动态调用对象方法的功能就是JAVA的反射。
反射中常用到的有Class,Field,Method,Constructor这几个类,这些类也是将类信息封装成相应的类

Class类常用到的有方法有



Method对象最重要的方法就是invoke,Constructor最重要的方法是newInstance
下面是对反射中比较常用的一些方法的举例

class MondayStudyReflect{
    private String getup;

    private String wash;



    public String review;


    public String getWash() {
        return wash;
    }

    public void setWash(String wash) {
        this.wash = wash;
    }

    public String getReview() {
        return review;
    }

    public void setReview(String review) {
        this.review = review;
    }


    private String getGetup() {
        return getup;
    }

    private void setGetup(String getup) {
        this.getup = getup;
    }

    public MondayStudyReflect(){
        System.out.println("无参构造方法");
    }

    public MondayStudyReflect(String wash,String review){
        System.out.println("无参构造方法 wash:"+wash+";review:"+review);
        this.wash = wash;
        this.review = review;

    }

    public void study(String message){
        System.out.println("公共有参方法调用:"+message);
    }


    private void summary() {
        System.out.println("私有无参方法调用");
    }

}

1.获取Class对象的三种方式
 

@Test
    public void getClassThreeMethod() throws Exception{
        Class classOne = MondayStudyReflect.class;
        MondayStudyReflect mondayStudyReflect = new MondayStudyReflect();
        Class classTwo =  mondayStudyReflect.getClass();
        Class classThree = Class.forName("com.example.findwork.reflect.MondayStudyReflect");
        if(classOne == classTwo && classTwo == classThree){
            System.out.println("三种方法获取的class对象是同一个");

            //最后输出结果
            //三种方法获取的class对象是同一个
        }

    }

一般都是通过调用Class的forName方法来获取类的Class对象,因为这个更加灵活,我们只需要获取到类的全限定名称就可以了
通过对象的getClass方法获取的话,我们已经有这个类的实例了,所以也不太需要class对象了。
 

2.获取类的相关属性

/**
     * 测试反射属性的获取
     * @throws Exception
     */
    @Test
    public void testReferectFields()throws Exception{
        Class classField = Class.forName("com.example.findwork.reflect.MondayStudyReflect");
        Field[] fieldArr = classField.getFields();
        System.out.println("获取所有的公开的类属性");
        for(Field field:fieldArr){
            System.out.println("属性名:"+field.getName()+";属性类型:"+field.getType());
        }

        Field[] fieldArrTwo = classField.getDeclaredFields();
        System.out.println("获取所有的类属性,包括私有属性");
        for(Field field:fieldArrTwo){
            System.out.println("属性名:"+field.getName()+";属性类型:"+field.getType());
        }

        Field filedReview =  classField.getField("review");
        System.out.println("通过属性名称获取公开属性");

        System.out.println("属性名:"+filedReview.getName()+";属性类型:"+filedReview.getType());

        Field filedWash =  classField.getDeclaredField("wash");
        System.out.println("通过属性名称获取私有属性");

        System.out.println("属性名:"+filedWash.getName()+";属性类型:"+filedWash.getType());
    }

输出结果

获取所有的公开的类属性
属性名:review;属性类型:class java.lang.String
获取所有的类属性,包括私有属性
属性名:getup;属性类型:class java.lang.String
属性名:wash;属性类型:class java.lang.String
属性名:review;属性类型:class java.lang.String
通过属性名称获取公开属性
属性名:review;属性类型:class java.lang.String
通过属性名称获取私有属性
属性名:wash;属性类型:class java.lang.String

3.获取类的公开方法和私有方法

/**
     * 测试反射方法的运用
     * @throws Exception
     */
    @Test
    public void testReflectMethod() throws Exception{
        Class classMethod = Class.forName("com.example.findwork.reflect.MondayStudyReflect");
        Method[] methodArr = classMethod.getMethods();
        System.out.println("===========获取所有的公开的类方法=========");
        for(Method method:methodArr){
            System.out.print("方法名:"+method.getName()+"   ");
        }

        Object object = classMethod.newInstance();//其实是得到了MondayStudyReflect的实例,等同于 new MondayStudyReflect
        Method methodSetWash =  classMethod.getMethod("setWash",String.class);
        methodSetWash.invoke(object,"调用公开方法");
        Method methodGetWash = classMethod.getMethod("getWash");
        String wash = methodGetWash.invoke(object).toString();
        System.out.println("通过反射调用方法获取到的参数 wash:"+wash);


        //调用私有方法
        Method methodSetGetup = classMethod.getDeclaredMethod("setGetup",String.class);
        methodSetGetup.setAccessible(true);//表示可以调用,没有设置这一步调用私有方法是会出现问题的
        methodSetGetup.invoke(object,"调用私有方法");

        Method methodgetGetup = classMethod.getDeclaredMethod("getGetup");
        methodgetGetup.setAccessible(true);//表示可以调用,没有设置这一步调用私有方法是会出现问题的
        String getUp = methodgetGetup.invoke(object).toString().toString();
        System.out.println("通过反射调用方法获取到的参数 getUp:"+getUp);


    }

输出结果

===========获取所有的公开的类方法=========
方法名:setWash   方法名:getWash   方法名:getReview   方法名:setReview   方法名:study   方法名:wait   方法名:wait   方法名:wait   方法名:equals   方法名:toString   方法名:hashCode   方法名:getClass   方法名:notify   方法名:notifyAll   无参构造方法
通过反射调用方法获取到的参数 wash:调用公开方法
通过反射调用方法获取到的参数 getUp:调用私有方法

可以看到获取公开所有方法的时候还会获取父类Object公开的方法

4.获取构造方法

/**
     * 测试构造方法的运用
     */
    @Test
    public void testReflectConsttruct() throws  Exception{
        Class classMethod = Class.forName("com.example.findwork.reflect.MondayStudyReflect");
        Constructor constructor = classMethod.getDeclaredConstructor();
        constructor.setAccessible(true);
        MondayStudyReflect nondayStudyReflect = (MondayStudyReflect)constructor.newInstance();


        Constructor constructorOne = classMethod.getConstructor(String.class,String.class);
        MondayStudyReflect nondayStudyReflectTwo = (MondayStudyReflect)constructorOne.newInstance("aaa","bbb");

    }

输出结果

无参构造方法
无参构造方法 wash:aaa;review:bbb

5.反射的好处和坏处

好处:

1.解耦类与类之间的关系,让类的调用更加灵活,向IOC的基本原理就是反射

坏处

1.调用性能没有直接调用好

2.破坏了类的封装性,可以调用私有方法和属性,最典型的就是破坏了单例模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值