Java基础巩固——反射
什么是反射
? 反射機(jī)制就是指程序運(yùn)行時(shí)能夠獲取自身的信息。在Java中,只要給出類的名字,就可以通過反射機(jī)制來獲取類的信息
哪里用的到反射機(jī)制
? 在jdbc中就是使用的反射來實(shí)例化對(duì)象,比如:Class.forName("com.mysql.jdbc.Driver.class").newInstance();
框架都用到反射機(jī)制,spring,hibernate、struts都是用反射機(jī)制實(shí)現(xiàn)的。
反射機(jī)制的優(yōu)點(diǎn)和缺點(diǎn)
? 為什么要用反射機(jī)制?直接創(chuàng)建對(duì)象不就可以了嗎,這就涉及到了動(dòng)態(tài)與靜態(tài)的概念,
??? 靜態(tài)編譯:在編譯時(shí)確定類型,綁定對(duì)象,即通過。
??? 動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類型,綁定對(duì)象。動(dòng)態(tài)編譯最大限度發(fā)揮了java的靈活性,體現(xiàn)了多
??? 態(tài)的應(yīng)用,有以降低類之間的藕合性。
??? 一句話,反射機(jī)制的優(yōu)點(diǎn)就是可以實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建對(duì)象和編譯,體現(xiàn)出很大的靈活性,特別是在J2EE的開發(fā)中.
它的靈活性就表現(xiàn)的十分明顯。比如,一個(gè)大型的軟件,不可能一次就把把它設(shè)計(jì)的很完美,當(dāng)這個(gè)程序編譯后,發(fā)布了,當(dāng)發(fā)現(xiàn)需要更新某些功能時(shí),我們不可能要用戶把以前的卸載,再重新安裝新的版本,假如這樣的話,這個(gè)軟件肯定是沒有多少人用的。采用靜態(tài)的話,需要把整個(gè)程序重新編譯一次才可以實(shí)現(xiàn)功能的更新,而采用反射機(jī)制的話,它就可以不用卸載,只需要在運(yùn)行時(shí)才動(dòng)態(tài)的創(chuàng)建和編譯,就可以實(shí)現(xiàn)該功
??? 能。
?????? 它的缺點(diǎn)是對(duì)性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它
??? 滿足我們的要求。這類操作總是慢于只直接執(zhí)行相同的操作。
利用反射機(jī)制能干什么
Class c=Class.forName("className");注明:className必須為全名,也就是得包含包名,比如,cn.netjava.pojo.UserInfo;
Object obj=c.newInstance();//創(chuàng)建對(duì)象的實(shí)例
獲取構(gòu)造器
Constructor getConstructor(Class[] params)//根據(jù)指定參數(shù)獲得public構(gòu)造器
Constructor[] getConstructors()//獲得public的所有構(gòu)造器
Constructor getDeclaredConstructor(Class[] params)//根據(jù)指定參數(shù)獲得public和非public的構(gòu)造器
Constructor[] getDeclaredConstructors()//獲得public的所有構(gòu)造器
獲取類的方法
? Method getMethod(String name, Class[] params),根據(jù)方法名,參數(shù)類型獲得方法
??? Method[] getMethods()//獲得所有的public方法
??? Method getDeclaredMethod(String name, Class[] params)//根據(jù)方法名和參數(shù)類型,獲得public和非public的方法
??? Method[] getDeclaredMethods()//獲得所以的public和非public方法
獲取類的屬性
Field getField(String name)//根據(jù)變量名得到相應(yīng)的public變量
?? ?? Field[] getFields()//獲得類中所以public的方法
????? Field getDeclaredField(String name)//根據(jù)方法名獲得public和非public變量
?? ?? Field[] getDeclaredFields()//獲得類中所有的public和非public方法
使用實(shí)例
?獲取類屬性:
public class TestGetField extends Object {private static final long serialVersionUID = -2862585049955236662L;public static void main(String args[]) throws Exception {Class<?> clazz = Class.forName("reflect.TestGetField");System.out.println("===============本類屬性===============");// 取得本類屬性Field[] fields = clazz.getDeclaredFields();getField(fields);System.out.println("==========實(shí)現(xiàn)的接口或者父類的屬性==========");// 取得實(shí)現(xiàn)的接口或者父類的屬性Field[] fatherField = clazz.getFields();getField(fatherField);}public static void getField(Field[] fields) {for (Field field : fields) {// 權(quán)限修飾符int mo = field.getModifiers();String priv = Modifier.toString(mo);Class<?> type = field.getType();System.out.println(priv + " " + type.getName() + " " + field.getName() + ";");}} }?
?獲取類的方法:
public class TestGetMethod implements Serializable{private static final String testString= "hello";public static void main(String args[]) throws Exception{Class<?> clazz = Class.forName("reflect.TestGetMethod");Method[] methods = clazz.getMethods();for (Method method :methods){Class<?> returnType = method.getReturnType();Class<?> para[] = method.getParameterTypes();int temp = method.getModifiers();System.out.print(Modifier.toString(temp));System.out.print(returnType.getName());System.out.print(method.getName());for (Class par:para){System.out.println(par.getName());}}} }?
?實(shí)例化類:
public class TestNewInstance {public static void main(String[] args) throws Exception{Class<?> class1 = null;class1 = Class.forName("reflect.User");// 第一種方法,實(shí)例化默認(rèn)構(gòu)造方法,調(diào)用set賦值User user = (User)class1.newInstance();user.setAge(20);user.setName("adf");System.out.println(user);// 第二種 取得全部的構(gòu)造函數(shù) 使用構(gòu)造函數(shù)賦值 } }class User {private int age;private String name;public User() {super();}public User(String name) {super();this.name = name;}public User(int age, String name) {super();this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User [age=" + age + ", name=" + name + "]";} }?
使用類的方法:
public class TestUseMethod {public static void main(String[] args)throws Exception{Class<?> clazz = Class.forName("reflect.TestUseMethod");// 調(diào)用reflect1方法Method method = clazz.getMethod("reflect1");method.invoke(clazz.newInstance());// 調(diào)用reflect2方法method = clazz.getMethod("reflect2", int.class, String.class);method.invoke(clazz.newInstance(),20,"test");}public void reflect1() {System.out.println("Java 反射機(jī)制 - 調(diào)用某個(gè)類的方法1.");}public void reflect2(int age, String name) {System.out.println("Java 反射機(jī)制 - 調(diào)用某個(gè)類的方法2.");System.out.println("age -> " + age + ". name -> " + name);} }?
動(dòng)態(tài)代理:
public class TestProxy {public static void main(String args[]) throws Exception{MyInvocationHandler demo = new MyInvocationHandler();Subject subject = (Subject) demo.bind(new RealSubject());System.out.println(subject.say("janti",20));} }interface Subject{public String say(String name, int age); }// 定義真實(shí)項(xiàng)目 class RealSubject implements Subject {public String say(String name, int age) {return name + " " + age;} }//如果想要完成動(dòng)態(tài)代理,首先需要定義一個(gè)InvocationHandler接口的子類,已完成代理的具體操作。class MyInvocationHandler implements InvocationHandler{private Object object = null;public Object bind(Object obj){this.object = obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object temp = method.invoke(this.object,args);return temp;} }?
轉(zhuǎn)載于:https://www.cnblogs.com/superfj/p/8711261.html
總結(jié)
以上是生活随笔為你收集整理的Java基础巩固——反射的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LVS DR模式部署
- 下一篇: Tomcat(1)介绍、jdk安装、安装