摘要:效率運(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(); ArrayListls = 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
近期在維護(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 正確的打開方式...
摘要:的動(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)或變量...
摘要:反射機(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è)方法和屬性;這種...
摘要:反射非常強(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)大和有用...
首先兩種方式在源碼里所在的位置: Class.newInstance() → Inside java.lang 包Constructor.newInstance() → Inside java.lang.reflect 包 使用方法: Class.newInstance(): Class.forName(HelloWorld).newInstance(); 或者 HelloWorl...
閱讀 1883·2021-11-25 09:43
閱讀 1522·2021-09-02 15:21
閱讀 3493·2019-08-30 15:52
閱讀 1529·2019-08-30 12:48
閱讀 1330·2019-08-30 10:57
閱讀 2959·2019-08-26 17:41
閱讀 706·2019-08-26 11:59
閱讀 1400·2019-08-26 10:41