反射(类类&反射实例化&动态方法调用&读写属性)

 

目录

一、认识反射

二、类类

三、反射实例化

四、反射动态方法调用

五、反射读写属性


 

一、认识反射

什么是反射: 反射是java语言中的一种机制,通过这种机制可以动态的实例化对象,读写属性,调用方法

反射的用途:许多开发框架都使用到了“反射”,还有jdbc中的类类,它的功能是获取方法、属性等类中的信息;调用类对象的方法;生成动态代理。

大量地使用反射,会造成性能下降


二、类类

什么是类类?

如动物类中的Dog类,Cat类和Person类

而Dog类就是动物类中的实例

那类类的获取方式有哪些?

1.类.class;

package com.lucy.fs;
public class Demo1 {
            public static void main(String[] args) throws Exception {
            //1.类.class
            Class clz1=Student.class; 
            //本工程没有此类,也可以编译通过
           // Object  newInstance=Class.forName("com.lucy.fs.Student").newInstance();
            }
}

2.类实例.getClass();

//2.类实例.getClass
            Student s=new Student(); 
            Class clz2=s.getClass();

3.Class.forName("类的全路径名");

    
            //3.Class.forName("类的全路径名")
            Class clz3=Class.forName("com.lucy.fs.Student");

 

 


 

三、反射实例化

方法:

        getConstructor(公有方法使用)

getDeclaredConstructor(私有方法使用)
        newInstance(实例化)

知识点2:
 * 1.无参数  公有的构造方法
 * 2.有参数  公有的构造方法
 * 3.有多个参数  公有的构造方法
 * 4. 私有的构造方法

package com.lucy.fs;

import java.lang.reflect.Constructor;

/**
 * @author lucy
 *
 */
public class Demo2 {
    public static void main(String[] args) throws Exception, IllegalAccessException {
        //创建对象
        Student stu1=new Student();//无参
        Student stu2=new Student("s002");//有参
        Student stu3=new Student("s001","哈哈");//多个参数

    }
}
 

 效果图如下

一般创建类的方法:

  ------以下均为反射的方法去创建对象

 

package com.lucy.fs;

import java.lang.reflect.Constructor;/**知识点2:反射实例化
 * 1.无参数  公有的构造方法
 * 2.有参数  公有的构造方法
 * 3.有多个参数  公有的构造方法
 * 4. 私有的构造方法
 * @author lucy
 *
 */

public class Demo2 {
    public static void main(String[] args) throws Exception, IllegalAccessException {
        //创建对象
        Student stu1=new Student();//无参

//            ------以下均为反射的方法去创建对象-------
        //获得类类
        Class<? extends Student> clz1=stu1.getClass();
        //默认调用无参    且公有的构造方法
//        1.无参数 公有构造方法
        Student stu4=clz1.newInstance();
//         2.有参数     公有的构造函数
        //拿到构造器对象 三个点代表可以传1个 2个 n个参数--->拿到一个参数为String的构造器
        Constructor<? extends Student>    c1= clz1.getConstructor(String.class);
         Student stu5=c1.newInstance("s001");
//         3.有多个(两个)   参数公有的构造方法
         Constructor<? extends Student>    c2 =clz1.getConstructor(String.class,String.class);
         Student stu6=c2.newInstance("s001","张三");
//         4.私有构造方法     要调用此法必须要拿到私有的构造器即getDeclaredConstructor
         Constructor<? extends Student>    c3= clz1.getDeclaredConstructor(Integer.class);
//         打开访问权限
         c3.setAccessible(true);
         Student stu7=c3.newInstance(17);//实例化

         
    }
}

效果图如下: 

 

 

 


四、反射动态方法调用

方法调用getMethod

getDeclaredMethod

具体步骤如下:


                 * 第一步:拿到类类
                 * 第二步:拿到方法对象
                 * 第三步: 调用对应的方法
                 

package com.lucy.fs;

import java.lang.reflect.Method;

/**知识点3:反射动态调用方法
 * @author lucy
 *1.调用无参的 公有构造方法
 *2.调用1个有参的 公有构造方法
 *3.调用2个有参的 公有构造方法
 *4.调用私有的构造方法
 *
 */

public class Demo3 {
        public static void main(String[] args) throws Exception {
                
//            1.拿到类类
            Class  clz=Class.forName("com.lucy.fs.Student");
//            2.拿到方法对象
//            name :方法名;parametertypes:方法对应的数
            Method m1 =clz.getMethod("hello");
//            3. 调用无参的方法:
//            第一个参数是:那个类实例对象; 第二个参数是:方法调用时的实参
//            m1.invoke方法调用的返回值就是方法对象本身的返回hello方法的返回值
            Object invoke1=m1.invoke(clz.newInstance());
            System.out.println(invoke1);
            
//            4.调用1个有参的公有方法
            Method m2=clz.getMethod("hello",String.class);
            Object invoke2= m2.invoke(clz.newInstance(),"李四" );
            System.out.println(invoke2);
//            5.有两个参数公有方法
//            略(与例4差不多)
//        6.私有的方法
            Method m3=clz.getDeclaredMethod("add",Integer.class,Integer.class);
//            打开权限
            m3.setAccessible(true);
            //调用方法 ---两个整数值的总合
            Object invoke3=m3.invoke(clz.newInstance(),3,3);
            System.out.println(invoke3);
            
            
        }
}

例1-5的效果图: 

 

 

例6效果图: 

 

 


五、反射读写属性

 用法:类类.getDeclaredFields();多个

类类.getDeclaredField();单个

 

package com.lucy.fs;

import java.lang.reflect.Field;

/**知识点4:反射读写属性
 * @author lucy
 *
 */
public class Demo4 {
    public static void main(String[] args) throws Exception {
            Student stu=new Student("s001","小洲");
            stu.age=18;
            //需求:要拿到所有属性值
//            一般做法如下:

                System.out.println("一般做法如下:");
            System.out.println("sname:"+stu.getSname());
            System.out.println("sid:"+stu.getSid());
               System.out.println("sage:"+stu.age);
    /**
     * 分析:
     * 上面代码所存在的问题:
     * 1.你如何得知此类有多少属性?
     * 2.假设student有30个属性嘞?
     * 
     */

==============================反射方法如下=============================================
//            反射从类类开始
            Class clz=stu.getClass();
//            拿到当前类的所有属性
            Field[] fields=clz.getDeclaredFields();//复数
//            System.out.println(fields.length);
//            for循环里的f代表每一个属性对象

        System.out.println("=============若用反射方法如下===============");
            for (Field f : fields) {//遍历属性对象
//                打开访问权限
                f.setAccessible(true);
                //通过属性对象拿到
                System.out.println(f.getName());//属性名
//                拿到属性对象的属性值
                System.out.println(f.get(stu));
            }

    }
}

 效果图如下:

 ===================================未经允许不得复制=============================================================

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值