成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java 反射(Reflection)

shengguo / 3103人閱讀

摘要:效率運(yùn)行效率使用反射減低程序的運(yùn)行效率。開發(fā)效率由于反射運(yùn)用到各個(gè)框架中,大大加快了開發(fā)的效率。

反射的核心就是Class對(duì)象,每一個(gè)類被jvm加載都會(huì)有一個(gè)對(duì)應(yīng)的class對(duì)象,這個(gè)class對(duì)象包含了這個(gè)類的結(jié)構(gòu)信息,反射就是會(huì)通過反射api反復(fù)操作這個(gè)class對(duì)象(屬性,方法,注解,構(gòu)造器,泛型),但是反射會(huì)降低程序的運(yùn)行效率,比普通方法要慢30倍,通過setAccessble(true) 跳過安全檢查(可以讀取private 的屬性),提高4倍的程序運(yùn)行效率
反射將普遍運(yùn)用到各個(gè)類型的框架。
效率:
1,運(yùn)行效率:使用反射 減低程序的運(yùn)行效率。
2,開發(fā)效率:由于反射運(yùn)用到各個(gè)java框架中,大大加快了開發(fā)的效率。

下面就是一些簡單的例子來具體闡述反射的一些特點(diǎn):

 package com.mk;
     public class Test{
     public static void main(String [] args){
        Foo foo = new Foo();//foo 表示foo的實(shí)例對(duì)象
        //任何一個(gè)類都是class的實(shí)例對(duì)象,有3鐘表達(dá)方式
        //1,任何一個(gè)類都有一個(gè)隱含的成員變量Class
        Class c1 = Foo.class;
        //2,通過getClass方法獲得
        Class c2 = foo.getClass();
        //不管是c1還是c2都代表Foo類的類類型,一個(gè)類只能是Class的實(shí)例對(duì)象
        System.out.println(c1==c2);//true
        //3,第三種表達(dá)方式
        Class c3 = null;
        try {
            c3 = Class.forName("com.mk.Foo");//類的全稱
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(c2==c3);//true

        //可以通過類的類類型創(chuàng)建該類的對(duì)象實(shí)例
        try {
            Foo f1 = (Foo) c1.newInstance();//需要無參數(shù)的構(gòu)造方法
            f1.print();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
     }
    }
       class Foo{
        void print(){
        System.out.println("print parent");
       }
    }

動(dòng)態(tài)加載類
new 創(chuàng)建對(duì)象 是靜態(tài)的加載類,在編譯的時(shí)刻就需要加載 所有可能使用到的類
通過動(dòng)態(tài)的加載類可以解決這個(gè)問題
運(yùn)行時(shí)刻加載 就是想用哪個(gè)就加載哪個(gè),不用就不加載。
通過反射api 操作類的方法

method.invoke(對(duì)象,參數(shù)列表)
    package com.mk;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    public class Test1 {
    public static void main(String[]args) throws
      NoSuchMethodException,      
        InvocationTargetException,
     IllegalAccessException {
        A a1 = new A();
        Class c = a1.getClass();//得到類類型
        Method m = c.getMethod("print",int.class,int.class);
        //方法的反射操作
        //a1.print(10,20);方法的反射操作是用m對(duì)象進(jìn)行方法的調(diào)用,和a1.print()的調(diào)用效果相同
        //方法如果沒有返回值返回null,如果有返回值就返回具體的值
        //Object obj = m.invoke(a1,new Object[]{10,20});
        //或者有幾個(gè)參數(shù)傳幾個(gè)參數(shù)
        Object ob = m.invoke(a1,10,20);
      }
     }
    class A{
    public void print(int a,int b){
        System.out.println(a+b);
      }
    }

通過class,method來認(rèn)識(shí)泛型的本質(zhì)

 package com.mk;
    java.lang.reflect.Method;
    java.util.ArrayList;
    class test2 {
    public static void main(String[] arg){
        ArrayList list = new ArrayList();
        ArrayList ls = new ArrayList();
        ls.add("hello");
        //ls.add(20);//泛型檢查錯(cuò)誤,20是加不進(jìn)去的
        Class c1 = list.getClass();
        Class c2 = ls.getClass();
        System.out.println(c1==c2);//反射的操作都是編譯之后的操作
        /**
         * c1==c2 結(jié)果返回true說明編譯之后的集合的泛型是去泛型化的,java中
         * 集合的泛型,是防止錯(cuò)誤輸入的,只有在編譯階段是有效的,在其他的階段都是
         * 無效的
         * 可以通過方法的反射來操作 繞過編譯
         */
          try {
            Method m = c2.getMethod("add",Object.class);
            m.invoke(ls,100);
            System.out.println(ls.size());
            System.out.println(ls);//[hello, 100] 結(jié)果int 是可以加進(jìn)去的
         } catch (Exception e) {
            e.printStackTrace();
        }

      }
    }

如何通過反射api 操作屬性,構(gòu)造器

public class User {
    private int id;
    private String name;
    //javabean 無參構(gòu)造器,用于java的反射機(jī)制的初始化
    public User() {
        
    }
    public User(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
        Class clazz 
             = Class.forName("com.test.reflection.Bean.User");
        //獲取名字
        System.out.println(clazz.getName());//包名+類名
        System.out.println(clazz.getSimpleName());
        //獲取屬性方法(重載,根據(jù)參數(shù)找方法)
        Field [] fs = clazz.getDeclaredFields();
        System.out.println(fs.length);//獲取所有的fields,不論public還是private
        Field [] field = clazz.getFields();//獲取公共屬性
        for(Field fields:fs){
            System.out.println("屬性:"+fields);
        }
        //獲取方法信息
        Method [] method 
             = clazz.getDeclaredMethods();//獲取所有的方法
        Method m1 = 
                clazz.getDeclaredMethod("getName",null);
        for(Method m:method){
            System.out.println("方法:"+m);
        }
        //獲取構(gòu)造器
        Constructor c1 = clazz.getConstructor(null);
        System.out.println("無參構(gòu)造器:"+c1);
        Constructor c2 = clazz.getConstructor(int.class,String.class);
        System.out.println("有參構(gòu)造器:"+c2);
        Constructor [] constructors 
            = clazz.getDeclaredConstructors();
        for(Constructor c:constructors){
            System.out.println("構(gòu)造器:"+c);
        }
        
        
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

 //動(dòng)態(tài)操作構(gòu)造器
      try {
        //通過反射api調(diào)用構(gòu)造方法
        User user = (User) clazz.newInstance();//其實(shí)是調(diào)用了user的無參構(gòu)造方法
        System.out.println(user);
        //調(diào)用有參構(gòu)造器
        Constructor constructor 
            = clazz.getDeclaredConstructor(int.class,String.class);
        User u 
            = (User) constructor.newInstance(12,"michael");
        System.out.println(u.getName());
        //通過反射api調(diào)用普通的方法
        User u1 
             = (User)clazz.newInstance();
        Method method 
             = clazz.getDeclaredMethod("setName", String.class);
        method.invoke(u1, "mike");//setName("mike");
        System.out.println(u1.getName());
        //通過反射操作屬性
        User u2 = (User) clazz.newInstance();
        Field  f 
             = clazz.getDeclaredField("name");//屬性必須是public的
        f.setAccessible(true);//不需要安全檢查,直接訪問
        f.set(u2, "mike2");
        System.out.println(u2.getName());//通過反射直接讀動(dòng)態(tài)值
        System.out.println(f.get(u2));
    } catch (Exception e) {
        e.printStackTrace();
    }

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64741.html

相關(guān)文章

  • ReflectionJava反射機(jī)制的應(yīng)用場(chǎng)景

    近期在維護(hù)公司項(xiàng)目的時(shí)候遇到一個(gè)問題,因?yàn)閷?shí)體類中的 set 方法涉及到了業(yè)務(wù)邏輯,因此在給對(duì)象賦值的過程中不能夠使用 set 方法,為了實(shí)現(xiàn)功能,所以采用了反射的機(jī)制給對(duì)象屬性賦值,借此機(jī)會(huì)也了解了反射的一些具體用法和使用場(chǎng)景,分以下兩點(diǎn)對(duì)反射進(jìn)行分析: 反射的優(yōu)勢(shì)和劣勢(shì) 反射的應(yīng)用場(chǎng)景 反射的優(yōu)勢(shì)和劣勢(shì) ??個(gè)人理解,反射機(jī)制實(shí)際上就是上帝模式,如果說方法的調(diào)用是 Java 正確的打開方式...

    浠ラ箍 評(píng)論0 收藏0
  • Java動(dòng)態(tài)性(2) - 之反射機(jī)制(Reflection)

    摘要:的動(dòng)態(tài)性反射機(jī)制動(dòng)態(tài)編譯動(dòng)態(tài)執(zhí)行代碼動(dòng)態(tài)字節(jié)碼操作動(dòng)態(tài)語言程序運(yùn)行時(shí)可以改變程序得結(jié)構(gòu)或變量類型典型語言等如下代碼不是動(dòng)態(tài)語言但有一定的動(dòng)態(tài)性我們可以利用反射機(jī)制字節(jié)碼操作獲得類似動(dòng)態(tài)語言的特性的動(dòng)態(tài)性讓編程的時(shí)候更加靈活反射機(jī)制反射機(jī)制指 1.Java的動(dòng)態(tài)性 反射機(jī)制 動(dòng)態(tài)編譯 動(dòng)態(tài)執(zhí)行JavaScript代碼 動(dòng)態(tài)字節(jié)碼操作 2.動(dòng)態(tài)語言 程序運(yùn)行時(shí),可以改變程序得結(jié)構(gòu)或變量...

    妤鋒シ 評(píng)論0 收藏0
  • ReflectionJava反射機(jī)制基礎(chǔ)

    摘要:反射機(jī)制是什么反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為語言的反射機(jī)制反射機(jī)制能做什么反射機(jī)制主要提供了以下功 反射機(jī)制是什么 反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種...

    hizengzeng 評(píng)論0 收藏0
  • Java 反射教程

    摘要:反射非常強(qiáng)大和有用。另外,反射可以用在映射結(jié)果集的列名到對(duì)象的方法。本教程將深入介紹反射。本教程還將清除一些關(guān)于范型信息在運(yùn)行時(shí)可用性的認(rèn)知混淆。類對(duì)象使用反射時(shí),起點(diǎn)通常是需要使用反射檢視的類的對(duì)象。 Java反射可以在運(yùn)行時(shí)檢視類、接口、屬性和方法,而無需在編譯時(shí)知道類名、方法名等等。它也同樣使用反射支持實(shí)例化新的對(duì)象、調(diào)用方法和get/set屬性值。 Java反射非常強(qiáng)大和有用...

    klivitamJ 評(píng)論0 收藏0
  • 通過Class.newInstance()和Constructor.newInstance()兩種反

    首先兩種方式在源碼里所在的位置: Class.newInstance() → Inside java.lang 包Constructor.newInstance() → Inside java.lang.reflect 包 使用方法: Class.newInstance(): Class.forName(HelloWorld).newInstance(); 或者 HelloWorl...

    dreamans 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<