JAVA基础:反射 (学习笔记)

反射

多态:父类做参数====扩展效果好
     父类做返回值====方法体内部是使用if选择判断,方法体仍然需要修改!
     ====解决方式:反射!

一,例子{初步感受}

美团外卖,支付例子:

下单支付的时候,可以选择微信支付,支付宝支付,吉林银行,北京银行。。。。

继承:抽象父类 支付方法

              微信 支付宝 银行

美团下单: 传入用户的选择,创建对应的对象,调用支付方法。

  • Fsther类

    package com.jr.reflect.demo1;
    
    public abstract class Father {
    
        public abstract void payOnLine();
    
    }
    
  • Ali类

    
    package com.jr.reflect.demo1;
    
    public class Ali extends Father {
        @Override
        public void payOnLine() {
    
            System.out.println("使用支付宝 完成支付功能!");
    
        }
    }
    
  • WeChat类

    package com.jr.reflect.demo1;
    
    public class WeChat extends Father {
        @Override
        public void payOnLine() {
            System.out.println("使用微信完成,支付功能,本单省去0.10元");
        }
    }
    
  • JLBank类

    package com.jr.reflect.demo1;
    
    public class JLBank extends Father {
        @Override
        public void payOnLine() {
    
            System.out.println("使用吉林银行支付,本次消费打折0.95");
    
        }
    }
    
  • BJBank类

    package com.jr.reflect.demo1;
    
    public class BJBank extends Father {
        @Override
        public void payOnLine() {
            System.out.println("使用北京银行,完成支付!");
        }
    }
    
  • MTWM类

    package com.jr.reflect.demo1;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class MTWM {
    
    /*    public void placeAnOrder(String str){
            if (str.equals("微信")) {
                new WeChat().payOnLine();
            }else if(str.equals("支付宝")){
                new Ali().payOnLine();
            }else{
                new JLBank().payOnLine();
            }
        }*/
    
        public void placeAnOrder(String str) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
    
    
            Class aClass = Class.forName(str);
            Object o = aClass.newInstance();
            Method payOnLine = aClass.getMethod("payOnLine");
            payOnLine.invoke(o);
            //反射学习的内容:学习如何获得构造方法,如何通过构造创建对象,如何获得属性,如何为属性赋值;如何获得方法,如何调用方法。
        }
    
    
    }
    
  • Text类

    package com.jr.reflect.demo1;
    
    import java.lang.reflect.InvocationTargetException;
    import java.util.Scanner;
    
    public class Test {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    
            MTWM mtwm = new MTWM();
            System.out.println("请输入你的支付方式:");
            String str = new Scanner(System.in).next();
            mtwm.placeAnOrder(str);
    
        }
    }
    

二,反射学习的内容

     Person类(属性准备)

package reflection.demo;

public class Person {

    private String idCard;
    private String name;
    private Integer age;

    public Person() {
        System.out.println("Person类的无参构造");
    }

    public Person(String idCard, String name, Integer age) {
        this.idCard = idCard;
        this.name = name;
        this.age = age;
        System.out.println("Person类的有参构造");
    }

    public String getIdCard() {
        return idCard;
    }

    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    protected void show() {
        System.out.println("无参方法---我是人类:身份证号是:" + idCard
                + "姓名是:" + name + "年龄是" + age);

    }

    protected void show(String idCard, String name, Integer age) {
        System.out.println("有参方法---我是人类:身份证号是:" + idCard
                + "姓名是:" + name + "年龄是" + age);

    }

    @Override
    public String toString() {
        return "Person{" +
                "idCard='" + idCard + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

 1.获得字节码文件对象的方式:

   (1)从源文件的角度,使用对象
 public static void main1(String[] args) {
        //从源文件的角度,使用对象
        Person person=new Person();
        person.setAge(23);
        person.show();
        System.out.println(person);
    }
   (2)从字节码文件的角度,使用对象
  1. 通过路径的方式 获得字节码文件对象:

  2. 通过类名 获得字节码文件对象:

  3. 通过对象名  获得字节码文件对象:

  4. 通过类加载器,加载指定路径字节码文件,  获得文件对象:

public static void main2(String[] args) throws ClassNotFoundException {
        //从字节码文件的角度,使用对象
        //1.通过路径的方式 获得字节码文件对象:
        Class class1 = Class.forName("com.jr.reflect.demo2.Person");//字节码文件在当前项目里的唯一位置:全局限定名 就是包名.类名

        //2.通过类名 获得字节码文件对象:
        Class class2= Person.class;

        //3.通过对象名  获得字节码文件对象:
        Person person=new Person();
        Class class3 = person.getClass();

        //4.通过类加载器,加载指定路径字节码文件,  获得文件对象:
        ClassLoader classLoader = Test1.class.getClassLoader();
        Class class4= classLoader.loadClass("com.jr.reflect.demo2.Person");
        System.out.println(class1==class2);
        System.out.println(class2==class3);
        System.out.println(class3==class4);

    }

2.如何获得构造方法,如何通过构造创建对象

  1. 执行单个构造方法
  2. 通过构造方法,实例化对象
  3. 输出对象
 public static void main3(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class cla=Class.forName("reflection.demo.Person");
        Constructor[] constructors=cla.getConstructors();
        for (Constructor c : constructors) {
            System.out.println(c);
        }
        //执行单个构造方法
        Constructor constructor=cla.getConstructor();
        //通过构造方法,实例化对象
        Object o=constructor.newInstance();
        //输出对象
        System.out.println(o);

        Constructor constructor1=cla.getConstructor(String.class,String.class,Integer.class);
        Object zs=constructor1.newInstance("123456789","张丹",34);
        System.out.println(zs);
    }

3.如何获得属性,如何为属性赋值;

 public static void main4(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
      //拿全部
        Class<?> cla = Class.forName("reflection.demo.Person");
      //Field[] fields = cla.getFields(); //只获得public修饰的属性
        Field[] fields = cla.getDeclaredFields();//只要是声明的属性都获得!
        for (Field f : fields) {
            System.out.println(f);
        }

        //拿单个
        Object o=cla.newInstance();
        Field name = cla.getDeclaredField("name");
        name.setAccessible(true);//暴力访问,不推荐使用(对象不是私有就不需要)
        name.set(o,"李四");
        System.out.println(o);

        Field idCard = cla.getDeclaredField("idCard");
        idCard.setAccessible(true);
        idCard.set(o,"123456789");
        System.out.println(o);

        Field age = cla.getDeclaredField("age");
        age.setAccessible(true);
        age.set(o,12);
        System.out.println(o);

    }

4.如何获得方法,如何调用方法。

 public static void main5(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        //拿字节码文件
        //拿全部  --数组
        Class<?> cla = Class.forName("reflection.demo.Person");
        Method[] methods = cla.getMethods();
        for (Method m : methods) {
            System.out.println(m);
        }
        //拿单个  --- 无参
        Method show = cla.getDeclaredMethod("show");
        show.invoke(cla.newInstance());

        //---有参
        Method show1 = cla.getDeclaredMethod("show",String.class,String.class,String.class);
        show1.invoke(cla.newInstance(),"123456789","王五",42);

    }

 5.反射 破 泛型集合:

泛型集合:只存在程序编译期,程序运行时没有泛型集合。
 public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
/*        ArrayList<String> list=new ArrayList<>();
        list.add("zhangsan");
        list.add("李四");
        list.add(34);
        System.out.println(list.size());*/

        Class  cla2= Class.forName("java.util.ArrayList");
        Object list = cla2.newInstance();
        Method add = cla2.getDeclaredMethod("add", Object.class);
        add.invoke(list,"张三");
        add.invoke(list,"李四");
        add.invoke(list,34);
        add.invoke(list,true);
        Method size = cla2.getDeclaredMethod("size");
        System.out.println(size.invoke(list));
        System.out.println(list);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值