摘要:效率運行效率使用反射減低程序的運行效率。開發效率由于反射運用到各個框架中,大大加快了開發的效率。
反射的核心就是Class對象,每一個類被jvm加載都會有一個對應的class對象,這個class對象包含了這個類的結構信息,反射就是會通過反射api反復操作這個class對象(屬性,方法,注解,構造器,泛型),但是反射會降低程序的運行效率,比普通方法要慢30倍,通過setAccessble(true) 跳過安全檢查(可以讀取private 的屬性),提高4倍的程序運行效率
反射將普遍運用到各個類型的框架。
效率:
1,運行效率:使用反射 減低程序的運行效率。
2,開發效率:由于反射運用到各個java框架中,大大加快了開發的效率。
下面就是一些簡單的例子來具體闡述反射的一些特點:
package com.mk; public class Test{ public static void main(String [] args){ Foo foo = new Foo();//foo 表示foo的實例對象 //任何一個類都是class的實例對象,有3鐘表達方式 //1,任何一個類都有一個隱含的成員變量Class Class c1 = Foo.class; //2,通過getClass方法獲得 Class c2 = foo.getClass(); //不管是c1還是c2都代表Foo類的類類型,一個類只能是Class的實例對象 System.out.println(c1==c2);//true //3,第三種表達方式 Class c3 = null; try { c3 = Class.forName("com.mk.Foo");//類的全稱 } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println(c2==c3);//true //可以通過類的類類型創建該類的對象實例 try { Foo f1 = (Foo) c1.newInstance();//需要無參數的構造方法 f1.print(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } class Foo{ void print(){ System.out.println("print parent"); } }
動態加載類
new 創建對象 是靜態的加載類,在編譯的時刻就需要加載 所有可能使用到的類
通過動態的加載類可以解決這個問題
運行時刻加載 就是想用哪個就加載哪個,不用就不加載。
通過反射api 操作類的方法
method.invoke(對象,參數列表) 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對象進行方法的調用,和a1.print()的調用效果相同 //方法如果沒有返回值返回null,如果有返回值就返回具體的值 //Object obj = m.invoke(a1,new Object[]{10,20}); //或者有幾個參數傳幾個參數 Object ob = m.invoke(a1,10,20); } } class A{ public void print(int a,int b){ System.out.println(a+b); } }
通過class,method來認識泛型的本質
package com.mk; java.lang.reflect.Method; java.util.ArrayList; class test2 { public static void main(String[] arg){ ArrayList list = new ArrayList(); ArrayListls = new ArrayList (); ls.add("hello"); //ls.add(20);//泛型檢查錯誤,20是加不進去的 Class c1 = list.getClass(); Class c2 = ls.getClass(); System.out.println(c1==c2);//反射的操作都是編譯之后的操作 /** * c1==c2 結果返回true說明編譯之后的集合的泛型是去泛型化的,java中 * 集合的泛型,是防止錯誤輸入的,只有在編譯階段是有效的,在其他的階段都是 * 無效的 * 可以通過方法的反射來操作 繞過編譯 */ try { Method m = c2.getMethod("add",Object.class); m.invoke(ls,100); System.out.println(ls.size()); System.out.println(ls);//[hello, 100] 結果int 是可以加進去的 } catch (Exception e) { e.printStackTrace(); } } }
如何通過反射api 操作屬性,構造器
public class User { private int id; private String name; //javabean 無參構造器,用于java的反射機制的初始化 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()); //獲取屬性方法(重載,根據參數找方法) 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); } //獲取構造器 Constructor c1 = clazz.getConstructor(null); System.out.println("無參構造器:"+c1); Constructor c2 = clazz.getConstructor(int.class,String.class); System.out.println("有參構造器:"+c2); Constructor [] constructors = clazz.getDeclaredConstructors(); for(Constructor c:constructors){ System.out.println("構造器:"+c); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } //動態操作構造器 try { //通過反射api調用構造方法 User user = (User) clazz.newInstance();//其實是調用了user的無參構造方法 System.out.println(user); //調用有參構造器 Constructor constructor = clazz.getDeclaredConstructor(int.class,String.class); User u = (User) constructor.newInstance(12,"michael"); System.out.println(u.getName()); //通過反射api調用普通的方法 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());//通過反射直接讀動態值 System.out.println(f.get(u2)); } catch (Exception e) { e.printStackTrace(); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64741.html
近期在維護公司項目的時候遇到一個問題,因為實體類中的 set 方法涉及到了業務邏輯,因此在給對象賦值的過程中不能夠使用 set 方法,為了實現功能,所以采用了反射的機制給對象屬性賦值,借此機會也了解了反射的一些具體用法和使用場景,分以下兩點對反射進行分析: 反射的優勢和劣勢 反射的應用場景 反射的優勢和劣勢 ??個人理解,反射機制實際上就是上帝模式,如果說方法的調用是 Java 正確的打開方式...
摘要:的動態性反射機制動態編譯動態執行代碼動態字節碼操作動態語言程序運行時可以改變程序得結構或變量類型典型語言等如下代碼不是動態語言但有一定的動態性我們可以利用反射機制字節碼操作獲得類似動態語言的特性的動態性讓編程的時候更加靈活反射機制反射機制指 1.Java的動態性 反射機制 動態編譯 動態執行JavaScript代碼 動態字節碼操作 2.動態語言 程序運行時,可以改變程序得結構或變量...
摘要:反射機制是什么反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法對于任意一個對象,都能夠調用它的任意一個方法和屬性這種動態獲取的信息以及動態調用對象的方法的功能稱為語言的反射機制反射機制能做什么反射機制主要提供了以下功 反射機制是什么 反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種...
首先兩種方式在源碼里所在的位置: Class.newInstance() → Inside java.lang 包Constructor.newInstance() → Inside java.lang.reflect 包 使用方法: Class.newInstance(): Class.forName(HelloWorld).newInstance(); 或者 HelloWorl...
閱讀 1854·2021-11-25 09:43
閱讀 1493·2021-09-02 15:21
閱讀 3457·2019-08-30 15:52
閱讀 1505·2019-08-30 12:48
閱讀 1299·2019-08-30 10:57
閱讀 2933·2019-08-26 17:41
閱讀 682·2019-08-26 11:59
閱讀 1372·2019-08-26 10:41