① java中invoke()的作用是什麼
用來執行一個方法,是反射中知識 。
就是調用類中的方法,最簡單的用法是可以把方法參數化invoke(class, method)。
比如你Test類里有一系列名字相似的方法setValue1、setValue2等等。
可以把方法名存進數組v[],然後循環里invoke(test,v[i]),就順序調用了全部setValue。
Java是一門面向對象編程語言,不僅吸收了C++語言的各種優點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特徵。
Java語言作為靜態面向對象編程語言的代表,極好地實現了面向對象理論,允許程序員以優雅的思維方式進行復雜的編程
② 什麼是反射技術什麼是靜態代理什麼是動態代理什麼是aop
JAVA的靜態代理與動態代理比較 一、概念 代理模式是常用的Java 設計模式,它的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理消息、過濾消息、把消息轉發給委託類,以及事後處理消息等。代理類與委託類之間通常會存在關聯關系,一個代理類的對象與一個委託類的對象關聯,代理類的對象本身並不真正實現服務,而是通過調用委託類的對象的相關方法,來提供特定的服務。按照代理類的創建時期,代理類可分為兩種。 靜態代理類: 由程序員創建或由特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。動態代理類:在程序運行時,運用反射機制動態創建而成。 二、靜態代理類 如下, HelloServiceProxy 類是代理類,HelloServiceImpl類是委託類,這兩個類都實現了HelloService介面。其中HelloServiceImpl類是HelloService介面的真正實現者,而HelloServiceProxy類是通過調用HelloServiceImpl 類的相關方法來提供特定服務的。HelloServiceProxy類的echo()方法和getTime()方法會分別調用被代理的HelloServiceImpl 對象的echo()方法和getTime()方法,並且在方法調用前後都會執行一些簡單的列印操作。 由此可見,代理類可以為委託類預處理消息、把消息轉發給委託類和事後處理消息等。 常式1 HelloService.java package proxy; import java.util.Date; public interface HelloService{ public String echo(String msg); public Date getTime(); } 常式2 HelloServiceImpl.java package proxy; import java.util.Date; public class HelloServiceImpl implements HelloService{ public String echo(String msg){ return "echo:"+msg; } public Date getTime(){ return new Date(); } } 常式3 HelloServiceProxy.java package proxy; import java.util.Date; public class HelloServiceProxy implements HelloService{ private HelloService helloService; //表示被代理的HelloService 實例 public HelloServiceProxy(HelloService helloService){ this.helloService=helloService; } public void setHelloServiceProxy(HelloService helloService){ this.helloService=helloService; } public String echo(String msg){ System.out.println("before calling echo()"); //預處理 String result=helloService.echo(msg); //調用被代理的HelloService 實例的echo()方法 System.out.println("after calling echo()"); //事後處理 return result; } public Date getTime(){ System.out.println("before calling getTime()"); //預處理 Date date=helloService.getTime(); //調用被代理的HelloService 實例的getTime()方法 System.out.println("after calling getTime()"); //事後處理 return date; } } 在Client1 類的main()方法中,先創建了一個HelloServiceImpl對象,又創建了一個HelloServiceProxy對象,最後調用HelloServiceProxy對象的echo()方法。 常式4 Client1.java package proxy; public class Client1{ public static void main(String args[]){ HelloService helloService=new HelloServiceImpl(); HelloService helloServiceProxy=new HelloServiceProxy(helloService); System.out.println(helloServiceProxy.echo("hello")); } } 運行Client1 類,列印結果如下: before calling echo() after calling echo() echo:hello 常式3 的HelloServiceProxy 類的源代碼是由程序員編寫的,在程序運行前,它的.class文件就已經存在了,這種代理類稱為靜態代理類。 三、動態代理類 與靜態代理類對照的是動態代理類,動態代理類的位元組碼在程序運行時由Java反射機制動態生成,無需程序員手工編寫它的源代碼。動態代理類不僅簡化了編程工作,而且提高了軟體系統的可擴展性,因為Java 反射機制可以生成任意類型的動態代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 介面提供了生成動態代理類的能力。 Proxy類提供了創建動態代理類及其實例的靜態方法。 (1)getProxyClass()靜態方法負責創建動態代理類,它的完整定義如下: public static Class<?> getProxyClass(ClassLoader loader, Class<?>[] interfaces) throws IllegalArgumentException 參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面。 (2)newProxyInstance()靜態方法負責創建動態代理類的實例,它的完整定義如下: public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws IllegalArgumentException 參數loader 指定動態代理類的類載入器,參數interfaces 指定動態代理類需要實現的所有介面,參數handler 指定與動態代理類關聯的 InvocationHandler 對象。 以下兩種方式都創建了實現Foo介面的動態代理類的實例: /**** 方式一 ****/ //創建InvocationHandler對象 InvocationHandler handler = new MyInvocationHandler(...); //創建動態代理類 Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class }); //創建動態代理類的實例 Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); /**** 方式二 ****/ //創建InvocationHandler對象 InvocationHandler handler = new MyInvocationHandler(...); //直接創建動態代理類的實例 Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler); 由Proxy類的靜態方法創建的動態代理類具有以下特點: 動態代理類是public、final和非抽象類型的; 動態代理類繼承了java.lang.reflect.Proxy類; 動態代理類的名字以「$Proxy」開頭; 動態代理類實現getProxyClass()和newProxyInstance()方法中參數interfaces指定的所有介面; Proxy 類的isProxyClass(Class<?> cl)靜態方法可用來判斷參數指定的類是否為動態代理類。只有通過Proxy類創建的類才是動態代理類; 動態代理類都具有一個public 類型的構造方法,該構造方法有一個InvocationHandler 類型的參數。 由Proxy類的靜態方法創建的動態代理類的實例具有以下特點: 1. 假定變數foo 是一個動態代理類的實例,並且這個動態代理類實現了Foo 介面,那麼「foo instanceof Foo」的值為true。把變數foo強制轉換為Foo類型是合法的: (Foo) foo //合法 2.每個動態代理類實例都和一個InvocationHandler 實例關聯。Proxy 類的getInvocationHandler(Object proxy)靜態方法返回與參數proxy指定的代理類實例所關聯的InvocationHandler 對象。 3.假定Foo介面有一個amethod()方法,那麼當程序調用動態代理類實例foo的amethod()方法時,該方法會調用與它關聯的InvocationHandler 對象的invoke()方法。 InvocationHandler 介面為方法調用介面,它聲明了負責調用任意一個方法的invoke()方法: Object invoke(Object proxy,Method method,Object[] args) throws Throwable 參數proxy指定動態代理類實例,參數method指定被調用的方法,參數args 指定向被調用方法傳遞的參數,invoke()方法的返回值表示被調用方法的返回值。 四、最後看一個實例: HelloServiceProxyFactory 類的getHelloServiceProxy()靜態方法負責創建實現了HelloService介面的動態代理類的實例。 常式5 HelloServiceProxyFactory.java package proxy; import java.lang.reflect.*; public class HelloServiceProxyFactory { /** 創建一個實現了HelloService 介面的動態代理類的實例 * 參數helloService 引用被代理的HelloService 實例 */ public static HelloService getHelloServiceProxy(final HelloService helloService){ //創建一個實現了InvocationHandler介面的匿名類的實例 InvocationHandler handler=new InvocationHandler(){ public Object invoke(Object proxy,Method method,Object args[])throws Exception{ System.out.println("before calling "+method); //預處理 Object result=method.invoke(helloService,args); //調用被代理的HelloService 實例的方法 System.out.println("after calling "+method); //事後處理 return result; } }; Class classType=HelloService.class; return (HelloService)Proxy.newProxyInstance(classType.getClassLoader(), new Class[]{classType}, handler); } } 如下所示的Client2 類先創建了一個HelloServiceImpl 實例,然後創建了一個動態代理類實例helloServiceProxy,最後調用動態代理類實例的echo()方法。 常式6 Client2.java package proxy; public class Client2{ public static void main(String args[]){ HelloService helloService=new HelloServiceImpl(); HelloService helloServiceProxy=HelloServiceProxyFactory.getHelloServiceProxy(helloService); System.out.println("動態代理類的名字為"+helloServiceProxy.getClass().getName()); System.out.println(helloServiceProxy.echo("Hello")); } } 運行Client2,列印結果如下: 動態代理類的名字為$Proxy0 before calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String) after calling public abstract java.lang.String proxy.HelloService.echo(java.lang.String) echo:Hello 從結果看出,動態代理類的名字為$Proxy0。
③ JAVA中反射是什麼
JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。
Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。而這也是Java被視為動態語言的一個關鍵性質。
Java反射的功能是在運行時判斷任意一個對象所屬的類,在運行時構造任意一個類的對象,在運行時判斷任意一個類所具有的成員變數和方法,在運行時調用任意一個對象的方法,生成動態代理。
(3)java反射靜態類擴展閱讀:
JAVA中反射實例:
1、Class superClass=clazz.getSuperclass();//獲取父類。
System.out.println("getSuperclass:"+superClass)。
2、Class[] interfaces=clazz.getInterfaces();//獲取實現介面。
System.out.println("getInterfaces:"+interfaces.length)。
3、Constructor[] cons=clazz.getConstructors();//構造方法。
System.out.println("getConstructors:"+cons.length)。
參考資料來源:網路: JAVA反射機制
④ java中利用反射為變數賦值的時候,為什麼變數需要聲明為static的
因為靜態只能接收靜態,反射獲得的值是靜態的。
例如:
public class Test{
public static void main(String[] args) {
aaa();
int n = num;
}
int num =100;
public void aaa(){}
}
aaa()和num會被強制轉為static類型;
可以這樣:
public static void main(String[] args) {
Test test = newTest();//實例化
test .aaa();
int n = test .num;
}
⑤ Java是動態語言還是靜態語言
Java是靜態類型語言,因為變數類型必須在聲明時標明,python、javascript等一些腳本語言是動態類型語言。
⑥ Java如何實現反射靜態載入和動態載入實例代碼詳解
1.Java動態載入類和靜態載入類的區別
new創建對象的方式稱作為靜態載入,而使用Class.forName("XXX")稱作為動態載入,它們倆本質的區別在於靜態載入的類的源程序在編譯時期載入(必須存在),而動態載入的類在編譯時期可以缺席(源程序不必存在)。
2.為什麼需要動態載入類
對於我自己的理解,動態載入類增加了程序的靈活性。比如一個程序中有50個功能,但你可能只會使用其中的一個,如果你用的是靜態載入的方式,你必須在編譯前提供100個功能的所有定義,否則無法編譯通過,若你使用的是動態載入機制,則不需要如此大費周章,用哪一個就定義哪一個即可。
靜態載入:
public class Office_Static {
public static void main(String[] args) {
//new 創建對象,是靜態載入類,在編譯時刻就需要載入所有的可能使用到的類
if("Word".equals(args[0])){
Word w = new Word();
w.start();
}
if("Excel".equals(args[0])){
Excel e = new Excel();
e.start();
}
}
}
這個程序編譯時必須有Word和Excel這兩個類存在才行,即使判斷後用不到Excel也要載入
動態載入:
介面OfficeAble :
public interface OfficeAble {
public void start();}
⑦ java中反射獲取靜態欄位為什麼也要傳入一個對象參數呢
欄位的值是依賴於某個對象的啊,
你拿到這個欄位set(這個欄位對應的某一對象,值)
完整翻譯過來就是給這個對象的某一欄位設置這個值
⑧ java的反射技術有什麼用
一、反射的概述
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的位元組碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼文件對應的Class類型的對象.
以上的總結就是什麼是反射
反射就是把java類中的各種成分映射成一個個的Java對象
例如:一個類有:成員變數、方法、構造方法、包等等信息,利用反射技術可以對一個類進行解剖,把個個組成部分映射成一個個對象。(其實:一個類中這些成員方法、構造方法、在加入類中都有一個類來描述)
如圖是類的正常載入過程:反射的原理在與class對象。
熟悉一下載入的時候:Class對象的由來是將class文件讀入內存,並為之創建一個Class對象。
希望對您有所幫助!~
⑨ 哪些項目中用到了Java反射機制
什麼是反射?將類的每個組件封裝到另一個對象中的過程稱為反射。其中,組件表示我們類的成員變數(Field)、構造方法(Constructor)和成員方法(Method)。反射使您可以在程序運行期間操作類對象,從而提高程序的靈活性。解耦提高了程序的可擴展性,提高了代碼重用率,便於外部調用。任何類別只要知道類別名稱,就可以知道該類別的所有屬性和方法。
反射像鏡子一樣,讓開發者知道這個類中有哪些成員。大多數人想知道Java有包,為什麼會有反射。破壞封裝性。通過允許外部訪問個人變數,使類不太安全。就我個人而言,反射機制實際上是上帝的模型。如果方法的調用是Java正確的打開方式,那麼反射機制就是上帝偷偷打開的後門。只要有相應的class存在,什麼都可以調用。那麼,上帝為什麼要打開這個後門呢?這包括靜態和動態概念。
⑩ 反射如何調用非靜態方法
靜態方法屬於類,所以會隨著類的載入而載入,
非靜態方法屬於對象,那就是說要調用這個非靜態方法,你得先得到這個類的實例,然後才能通過這個實例去調用這個非靜態方法
Java反射機制(創建Class對象的三種方式)