Java动态加载一个类的几种方法以及invoke
一.加載一個類的幾種方法
接口
IUser
package org.me.javaapp;/**** @author Administrator*/
public interface IUser {}
User.java
/** To change this license header, choose License Headers in Project Properties.* To change this template file, choose Tools | Templates* and open the template in the editor.*/
package org.me.javaapp;public class User implements IUser{private String name;private int id;/*** @return the name*/public String getName() {return name;}/*** @param name the name to set*/public void setName(String name) {this.name = name;}/*** @return the id*/public int getId() {return id;}/*** @param id the id to set*/public void setId(int id) {this.id = id;}
}
主類
public static void main(String[] args) throws ClassNotFoundException{ try{Class c1=Class.forName("org.me.javaapp.User");Class c2=User.class;Object o1=c1.newInstance();Object o2=c2.newInstance();User u1=new User();Class c3=u1.getClass();/*this.getClass.getClassLoader();// 使用當前類的ClassLoader Thread.currentThread().getContextClassLoader(); // 使用當前線程的ClassLoader ClassLoader.getSystemClassLoader(); // 使 用系統ClassLoader,即系統的入口點所使用的ClassLoader。(注意,system ClassLoader與根 ClassLoader并不一樣。JVM下system ClassLoader通常為App ClassLoader) */ClassLoader clo=Thread.currentThread().getContextClassLoader();Class c4=clo.loadClass("org.me.javaapp.User");Field[] fs = c1.getDeclaredFields();for(Field field:fs){ System.out.println("獲得屬性的修飾符,例如public,static等等 >>"+Modifier.toString(field.getModifiers()));System.out.println("屬性的類型的名字 >>"+field.getType());System.out.println("屬性的名字 >>"+field.getName());}Method[] ms = c1.getDeclaredMethods();for(Method field:ms){ System.out.println("獲得方法的修飾符,例如public,static等等 >>"+Modifier.toString(field.getModifiers()));System.out.println("方法的參數個數 >>"+field.getParameterCount());System.out.println("方法的名字 >>"+field.getName());}System.out.println("c1的父類>>"+c1.getSuperclass());Class[] cs=c1.getInterfaces();for(Class field:cs){ System.out.println("接口的名字 >>"+field.getName());}System.out.println(">>>>>>>>>>>");}catch (Exception ex){System.out.println(ex.toString());}}
輸出:
獲得屬性的修飾符,例如public,static等等 >>private
屬性的類型的名字 >>class java.lang.String
屬性的名字 >>name
獲得屬性的修飾符,例如public,static等等 >>private
屬性的類型的名字 >>int
屬性的名字 >>id
獲得方法的修飾符,例如public,static等等 >>public
方法的參數個數 >>0
方法的名字 >>getName
獲得方法的修飾符,例如public,static等等 >>public
方法的參數個數 >>0
方法的名字 >>getId
獲得方法的修飾符,例如public,static等等 >>public
方法的參數個數 >>1
方法的名字 >>setName
獲得方法的修飾符,例如public,static等等 >>public
方法的參數個數 >>1
方法的名字 >>setId
c1的父類>>class java.lang.Object
接口的名字 >>org.me.javaapp.IUser
參考:JAVA中的反射機制
獲取方法,和構造方法,不再詳細描述,只來看一下關鍵字:
方法關鍵字
含義
getDeclaredMethods()
獲取所有的方法
getReturnType()
獲得方法的放回類型
getParameterTypes()
獲得方法的傳入參數類型
getDeclaredMethod("方法名",參數類型.class,……)
獲得特定的方法
?
?
構造方法關鍵字
含義
getDeclaredConstructors()
獲取所有的構造方法
getDeclaredConstructor(參數類型.class,……)
獲取特定的構造方法
?
?
父類和父接口
含義
getSuperclass()
獲取某類的父類
getInterfaces()
獲取某類實現的接口
ClassLoader 詳解及用途
ClassLoader主要對類的請求提供服務,當JVM需要某類時,它根據名稱向ClassLoader要求這個類,然后由ClassLoader返回這個類的class對象。
java中的反射總結?【舉例不錯,很全面】
二.Invoke
一個方法可以生成多個Method對象,但只有一個root對象,主要用于持有一個MethodAccessor對象,這個對象也可以認為一個方法只有一個,相當于是static的,因為Method的invoke是交給MethodAccessor執行的。
package org.me.javaapp;public class Child extends Person{public void say(String s) {System.out.println("Hello invork>>>"+s);}public void add(int a,int b) {a+=b;System.out.println("a+b="+a);}
}
invoke調用
package org.me.test;import java.lang.reflect.Method;
import org.junit.Test;public class TestInvoke {@Testpublic void testSingleton() throws Exception {Class<?> clz = Class.forName("org.me.javaapp.Child");Object o = clz.newInstance();Method m = clz.getMethod("add", int.class,int.class);m.invoke(o, 1,2);m = clz.getDeclaredMethod("say", String.class);m.invoke(o,"http://blog.csdn.net/unix21/");}
}
參考:
java中的反射,invoke方法
getMethod方法第一個參數指定一個需要調用的方法名稱
第二個參數是需要調用方法的參數類型列表,是參數類型!如無參數可以指定null。
參數必須和方法中一樣int和Integer,double和Double被視為不同的類型。
反射中getMethods 與 getDeclaredMethods 的區別
public Method[] getMethods()返回某個類的所有公用(public)方法包括其繼承類的公用方法,當然也包括它所實現接口的方法。
public Method[] getDeclaredMethods()對象表示的類或接口聲明的所有方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。
當然也包括它所實現接口的方法。
JAVA深入研究——Method的Invoke方法【非常深入,講了實現細節】
可以看到Method.invoke()實際上并不是自己實現的反射調用邏輯,而是委托給sun.reflect.MethodAccessor來處理。?
每個實際的Java方法只有一個對應的Method對象作為root。這個root是不會暴露給用戶的,而是每次在通過反射獲取Method對象時新創建Method對象把root包裝起來再給用戶。
在第一次調用一個實際Java方法對應得Method對象的invoke()方法之前,實現調用邏輯的MethodAccessor對象還沒創建;
等第一次調用時才新創建MethodAccessor并更新給root,然后調用MethodAccessor.invoke()真正完成反射調用。
java反射機制詳解 及 Method.invoke解釋
JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
Java反射機制主要提供了以下功能: 在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變量和方法;在運行時調用任意一個對象的方法;生成動態代理。
三.Class<?>與Class
Class<?> clz = Class.forName("org.me.javaapp.Child");Class clzz = Class.forName("org.me.javaapp.Child");Object o = clzz.newInstance();Method m = clz.getMethod("add", int.class,int.class);m.invoke(o, 1,2);m = clz.getDeclaredMethod("say", String.class);m.invoke(o,"http://blog.csdn.net/unix21/");效果是一樣的。
總結
以上是生活随笔為你收集整理的Java动态加载一个类的几种方法以及invoke的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAX-WS Web 服务开发调用和数据
- 下一篇: Spring MVC 4