反射机制

java反射机制就是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法

对于任意一个对象,都能够调用它的任意一个方法和属性

这种动态获取信息以及动态调用方法的功能称为java语言的反射机制

package com.monfolld.reflect;

public class Person {
    private int age;
    private String name;
    public Person(int age,String name){
        super();
        this.age=age;
        this.name=name;
        System.out.println("Person param run..."+this.name+":"+this.age);
    }
    public Person(){
        super();
        System.out.println("person run");
    }
    public void show(){
        System.out.println(name+"...show"+age);
    }
    private void privateMethod(){
        System.out.println("method run");
    }
    public void paramMethod(String str,int num){
        System.out.println("paramMethod run..."+str+":"+num);
    }
    public static void staticMethod(){
        System.out.println("static method run ....");
    }
}

 

package com.monfolld.reflect;


public class ReflectDemo {
    public static void main(String[] args)throws ClassNotFoundException{
        getClassObject_3();
    }
    /*方式一:
    获取字节码对象的方式
    * 1.Object类中的getClass()方法的
    * 想要用这种方式,必须要明确具体的类,并穿件对象
    *
    * */
    public static void getClassObject_1(){
        Person p=new Person();
        Class clazz=p.getClass();

        Person p1=new Person();
        Class clazz1=p1.getClass();

        System.out.println(clazz==clazz1);
    }
    /*方式二:
    * 2.任何数据类型都具备一个静态的属性.class来获取其对应的class对象
    * 相对简单,但是还是要明确类,用到类中的静态成员
    * 还是不够扩展
    * */
    private static void getClassObject_2(){
        Class clazz=Person.class;
        Class clazz1=Person.class;
        System.out.println(clazz==clazz1);
    }
    /*方式三:
    * 只要通过给定的字符串名称九合一获取该类,更为拓展
    * 可是用Class类中的方法完成
    * 该方法就是forName*/
    public static void getClassObject_3()throws ClassNotFoundException{
        String className="com.monfolld.reflect.Person";
        Class clazz= Class.forName(className);
        System.out.println(clazz);
    }

}
package com.monfolld.reflect;

import java.lang.reflect.Constructor;

public class ReflectDemo2 {
    public static void main(String[] args) throws Exception{
        createNewObject_2();
    }
    public static void createNewObject() throws ClassNotFoundException,InstantiationException,IllegalAccessException{
        //早起:new时候,先根据被new的类名称寻找该类的字节码文件,并加载进内存,
        //并创建该字节码文件对象,并借着创建字节文件的对应Person对象
       /* com.monfolld.reflect.Person p=new com.monfolld.reflect.Person();*/

        //现在:
        String name= "com.monfolld.reflect.Person";
        //寻找该名称类文件,并加载进内存,产生class对象
        Class clazz=Class.forName(name);
        //如何产生该类的对象呢?
        Object obj=clazz.newInstance();
    }
    public static void  createNewObject_2() throws Exception{
        /*com.monfolld.reflect.Person p=new com.monfolld.reflect.Person(39,"小强");*/
        /*当获取指定名称对应类中的所体现的对象时,
        * 而该对象初始化不使用空参数构造该怎么办呢?
        * 既然是获取指定的构造函数进行对象的初始化
        * 所以应该先获取到该构造函数,通过字节码文件对象即可完成
        * 该方法是:getConstructor(paramterTypes)*/
        String name="com.monfolld.reflect.Person";
        Class clazz=Class.forName(name);
        //获取到了指定的构造函数对象
        Constructor constructor=clazz.getConstructor(int.class,String.class);

        //通过该构造器对象的newInstance方法进行对象的初始化
        Object obj=constructor.newInstance(39,"小明");
    }
}
package com.monfolld.reflect;

import java.lang.reflect.Field;

public class ReflectDemo3 {
    public static void main(String[] args)throws Exception{
        getFieldDemo();
    }
    public static void getFieldDemo() throws Exception{
        Class clazz=Class.forName("com.monfolld.reflect.Person");

        Field field=null;//clazz.getField("age");//只能获取共有的

        field=clazz.getDeclaredField("age");//只获取本类,但包含私有
        //对私有字段的访问取消权限检查,暴力访问
        field.setAccessible(true);

        Object obj=clazz.newInstance();//创建对象
        //field.set(obj,89);

        Object o=field.get(obj);//获取对象返回的值
        System.out.println(o);
    }
}
package com.monfolld.reflect;

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

public class ReflectDemo4 {
    public static void main(String[] args)throws Exception{
        getMethodDemo_3();
    }
    public static void getMethodDemo()throws Exception{
        Class clazz=Class.forName("com.monfolld.reflect.Person");
        Method[] methods=clazz.getMethods();//获取的都是共有方法
        methods=clazz.getDeclaredMethods();//只获取本类中的所有方法,包含私有
        for(Method method:methods){
            System.out.println(method);
        }
    }
    public static void getMethodDemo_2()throws Exception {
        Class clazz=Class.forName("com.monfolld.reflect.Person");
        Method method=clazz.getMethod("show",null);//获取空参数一般方法
        //Object obj=clazz.newInstance();
        Constructor constructor=clazz.getConstructor(int.class,String.class);
        Object obj=constructor.newInstance(37,"小明");
        method.invoke(obj,null);
    }
    public static void getMethodDemo_3()throws Exception{
        Class clazz=Class.forName("com.monfolld.reflect.Person");
        Method method=clazz.getMethod("paramMethod", String.class, int.class);
        Object obj=clazz.newInstance();
        method.invoke(obj,"小强",89);
    }
}

反射练习

电脑运行

package com.monfolld.reflect.test;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;

/*电脑运行*/
public class ReflectTest {
    public static void main(String[] args)throws Exception{
        MainBoard mb=new MainBoard();
        mb.run();
        //每次添加一个设备都需要修改代码传递一个新创建的对象
        //mb.usePCI(new SoundCard());
        //能不能不修改代码就可以完成这个动作
        //不能new来完成,俄日是只获取其class文件。在内部实现创建对象的动作。
        File configFile=new File("pci.properties");
        Properties prop=new Properties();
        FileInputStream fis=new FileInputStream(configFile);
        prop.load(fis);
        for (int x=0;x<prop.size();x++){
          String pciName=  prop.getProperty("pci"+(x+1));

          Class clazz=Class.forName(pciName);//用class去加载这个pci子类

            PCI p=(PCI)clazz.newInstance();

            mb.usePCI(p);
        }
        fis.close();
    }
}

 主板

package com.monfolld.reflect.test;

public class MainBoard {
    public void run(){
        System.out.println("main board run...");
    }
    public void usePCI(PCI p) {//PCI p=new SoundCard();
        if (p != null) {
            p.open();
            p.close();
        }
    }
}

 声卡网卡

package com.monfolld.reflect.test;

public class SoundCard implements PCI {
    public void open(){
        System.out.println("sound open");
    }
    public void close(){
        System.out.println("sound close");
    }
}
package com.monfolld.reflect.test;

public class NetCard implements PCI {
        public void open(){
            System.out.println("net open");
        }
        public void close(){
            System.out.println("net close");
        }
}

 接口

package com.monfolld.reflect.test;

public interface PCI {
        public void open();
        public void close();
}

pci.properties文件

pci1=com.monfolld.reflect.test.SoundCard
pci2=com.monfolld.reflect.test.NetCard

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值