java笔记--反射机制

java反射机制:

在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态掉作用对象的方法的功能成为Java的反射机制--动态获取类中的信息,可理解为对类的解剖。

public class Person {
    
    private int age;
    private String name;
    public Person(String name,int age) {
        super();
        this.age = age;
        this.name = name;
    }
    public Person() {
        super();
        System.out.println("person run");
    }
    
    public void show(){
        System.out.println(name+"...show run..."+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..");
    }
}
要想对字节码文件进行解剖,必须要有字节码文件对象。
public class ReflectDemo {

    public static void main(String[] args) throws ClassNotFoundException {
        
        getClassObject_1();
        getClassObject_2();
        getClassObject_3();

    }
    
    /*
    3,只要通过给定的类的字符串名字就可以获取该类,扩展性更强。
    可用Class类中的方法--forName完成。
    这种方式只要有名称即可。
     */
    public static void getClassObject_3() throws ClassNotFoundException {

        String className="cn.itcast.bean.Person";
        
        Class clazz=Class.forName(className);
        
        System.out.println(clazz);
    }
    
    /*
    2,任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。
    相对简单,但还是要明确类中的静态成员。
    扩展性不够。
    */
    public static void getClassObject_2() {
        
        Class clazz=Person.class;
        
        Class clazz1=Person.class;
        
        System.out.println(clazz==clazz1);
        
    }
    
    /*
    获取字节码对象的方式:
    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);
    }

}

运行:
public class ReflectDemo2 {
    
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, Exception {

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

    public static void createNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
        
        
        //早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
//      并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象.
//      cn.itcast.bean.Person p = new cn.itcast.bean.Person();
        
        //现在:
        String name = "cn.itcast.bean.Person";
        //找寻该名称类文件,并加载进内存,并产生Class对象。
        Class clazz = Class.forName(name);
        //如何产生该类的对象呢?
        Object obj  = clazz.newInstance();  
    }
}

运行:
public class ReflectDemo3 {

    public static void main(String[] args) throws Exception {
        
        getFieldDemo();
        
    }

    /*
     * 获取字节码文件中的字段。
     */
    public static void getFieldDemo() throws Exception {
        
        Class clazz = Class.forName("cn.itcast.bean.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);
        
//      cn.itcast.bean.Person p = new cn.itcast.bean.Person();
//      p.age = 30;
        
    }   
}

运行:
public class ReflectDemo4 {

    public ReflectDemo4() {
    }
    
    public static void main(String[] args) throws Exception {

        getMethodDemo_3();
        
    }
    
    

    public static void getMethodDemo_3() throws Exception {
        
        Class clazz = Class.forName("cn.itcast.bean.Person");
        
        Method method = clazz.getMethod("paramMethod", String.class,int.class);
        
        Object obj = clazz.newInstance();
        
        method.invoke(obj, "小强",89);
        
        
    }

    public static void getMethodDemo_2() throws Exception {
        
        Class clazz = Class.forName("cn.itcast.bean.Person");
        
        Method method = clazz.getMethod("show", null);//获取空参数一般方法。
        
//      Object obj = clazz.newInstance();
        Constructor constructor = clazz.getConstructor(String.class,int.class);
        Object obj = constructor.newInstance("小明",37);
        
        method.invoke(obj, null);   
    }

    /*
     * 获取指定Class中的所有公共函数。
     */
    public static void getMethodDemo() throws Exception {
        
        Class clazz = Class.forName("cn.itcast.bean.Person");
        
        Method[] methods  = clazz.getMethods();//获取的都是公有的方法。 
        methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 
        for(Method method : methods){
            System.out.println(method);
        }   
    }
}

运行:
应用:
public interface PCI {
    
    public void open();
    public void close();

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

}
public class NetCard implements PCI {

    @Override
    public void open() {
        System.out.println("net open");
    }

    @Override
    public void close() {
        System.out.println("net close");
    }

}
public class Mainboard {

    public void run() {
        System.out.println("main board run....");
    }

    public void usePCI(PCI p) {//PCI p = new SouncCard();
        if (p != null) {
            p.open();
            p.close();
        }
    }
}
/*
 * 电脑运行。 
 */
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();
        
        
    }

}

配置文件:

运行:
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,858评论 25 707
  • 何为智者,能够找到关键点,用恰到好处的方法解决问题。何为愚者,不能找到关键点,不能找出合适的方法处理问题。愚者的特...
    茨粢思阅读 219评论 0 0
  • 对于从未做过销售的我来说,地推是一件想都不敢想的事,但人生总有第一次。终于在10月20日和朋友一起开始了地推之路!...
    行动等于财富阅读 2,103评论 0 0
  • 本文是听完《伯凡非常道》节目后的复述。 在商家的推动下,节日越来越多,国人现在什么节日都过,西方的圣诞节,感恩节,...
    轻舟阅读 761评论 0 0
  • 在忙碌的空隙中,抽出一个小时奔向书店,随意翻开一本周先生的书。哲学出身的他,总会不经意间让自己的作品透出有些...
    苏小钱阅读 3,178评论 0 1