1. java反射機制怎樣調用類的私有方法
的一段簡易實例代碼如下:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author thomaslwq
* @version 創建時間:Sep 4, 2012 9:53:49 PM
* 類說明
*/
public class ReflectionTest {
public static void setObjectColor(Object obj) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAcces***ception, InvocationTargetException{
Class cls = obj.getClass();
//獲得類的私有方法
Method method = cls.getDeclaredMethod("privateMethod", null);
method.setAccessible(true); //沒有設置就會報錯
//調用該方法
method.invoke(obj, null);
}
public static void main(String args[]) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAcces***ception, InvocationTargetException{
setObjectColor(new MyTest());
}
}
//測試類
class MyTest{
public void setMyTest(){
System.out.println("setMyTest");
}
/**
類的私有方法
**/
private void privateMethod(){
System.out.println("調用了 private Method");
}
}
2. java反射方法調用問題
int是基本類型沒錯,因此,在用反射調用時,應明確使用Integer才行。
由於參數是從資料庫內里來容的(ResultSet),因此,要看資料庫的定義,以及資料庫的類型。
比如,對於Oracle 定義的任何數值類型欄位,都會返回Decimal對象,由於float類型能運行,推斷應該不使用的ORACLE,還是看你的資料庫定義吧,實在不行,就要做下面的工作,增加一個TypeConvertor定義,其中實現將資料庫返回的對象轉換成方法參數所需的類型,針對幾種基本數據類型進行簡單的轉換,就不需要依賴資料庫了。
1樓的是想自己做持久類框架??
3. 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反射機制
4. java中反射的三種方法是
java中反射的三種方法:
1. 通過Object類的getClass方法來獲取
java.lang.Object中定義有getClass方法:public final Class getClass()
所有Java對象都具備這個方法,該方法用於返回調用該方法的對象的所屬類關聯的Class對象,例如:
Date date1 = new Date();
Date date2 = new Date();
Class c1 = date1.getClass();
Class c2 = date2.getClass();
System.out.println(c1.getName());
// java.util.Date
System.out.println(c1 == c2);
// true
上面的代碼中,調用Date對象date1的getClass方法將返回用於封裝Date類信息的Class對象。
這里調用了Class類的getName方法:public String getName(),這個方法的含義很直觀,即返回所封裝的類的名稱。
需要注意的是,代碼中的date1和date2的getClass方法返回了相同的Class對象(c1==c2的值為true)。這是因為,對於相同的類,JVM只會載入一次,而與該類對應的Class對象也只會存在一個,無論該類實例化了多少對象。
另外,需要強調的是,當一個對象被其父類的引用或其實現的介面類型的引用所指向時,getClass方法返回的是與對象實際所屬類關聯的Class對象。例如:
List list = new ArrayList();
System.out.println(list.getClass().getName()); // java.util.ArrayList
上面的代碼中,語句list.getClass()方法返回的是list所指向對象實際所屬類java.util.ArrayList對應的 Class對象而並未java.util.List所對應的Class對象。有些時候可以通過這個方法了解一個對象的運行時類型,例如:
HashSet set = new HashSet();
Iterator it = set.iterator();
System.out.println(it.getClass().getName()); //java.util.HashMap$KeyIterator
從代碼可以看出,HashSet的iterator方法返回的是實現了Iterator介面的HashMap內部類(KeyIterator)對象。
因為抽象類和介面不可能實例化對象,因此不能通過Object的getClass方法獲得與抽象類和介面關聯的Class對象。
2. 使用.class的方式
使用類名加「.class」的方式即會返回與該類對應的Class對象。例如:
Class clazz = String.class;
System.out.println(clazz.getName()); // java.lang.String
這個方法可以直接獲得與指定類關聯的Class對象,而並不需要有該類的對象存在。
3. 使用Class.forName方法
Class有一個著名的static方法forName:public static Class forName(String className) throws ClassNotFoundException
該方法可以根據字元串參數所指定的類名獲取與該類關聯的Class對象。如果該類還沒有被裝入,該方法會將該類裝入JVM。
該方法聲明拋出ClassNotFoundException異常。顧名思義,當該方法無法獲取需要裝入的類時(例如,在當前類路徑中不存在這個類),就會拋出這個異常。
例如,如果當前類路徑中存在Foo類:
package org.whatisjava.reflect;
public class Foo {
public Foo() {
System.out.println("Foo()");
}
static {
System.out.println("Foo is initialized");
}
}
運行下面的代碼:
Class clazz = Class.forName("org.whatisjava.reflect.Foo");
控制台會有如下輸出:
Foo is initialized
Class.forName("org.whatisjava.reflect.Foo")首先會將reflection.Foo類裝入JVM,並返回與之關聯的Class對象。JVM裝入Foo類後對其進行初始化,調用了其static塊中的代碼。需要注意的是:forName方法的參數是類的完 整限定名(即包含包名)。
區別於前面兩種獲取Class對象的方法:使用Class.forName方法所要獲取的與之對應的Class對象的類可以通過字元串的方式給定。該方法通常用於在程序運行時根據類名動態的載入該類並獲得與之對應的Class對象。
通過上面的文章相信你對java的反射機制有了一定的認識,同時也對java中Class類的用法有了比較清晰的理解,在我們實際工作的過程中,我們不斷的運用java知識來解決實際生活中的問題的時候我們就能對java反射機制有一個更深入的理解!
二、代碼示例
1.ClassTest.java
[java] view plain
/**
* java中Class類的使用
*/
import java.io.*;
import java.lang.reflect.*;
public class ClassTest1 {
public ClassTest1(){
}
public static void main(String[] args) throws Exception{
ClassTest1 test=new ClassTest1();
ClassTest1 test1=test.getClass().newInstance();
//test1=test;
test.printMessage();
test1.printMessage();
System.out.println(test.hashCode());
System.out.println(test1.hashCode());
Method[] method=test1.getClass().getMethods();
for(Method m :method){
System.out.println(m.getDeclaringClass());
System.out.println(m.getName());
}
}
public void printMessage(){
System.out.println("Created successful!");
}
}
運行結果:
[plain] view plain
Created successful!
Created successful!
14576877
12677476
class ClassTest1
printMessage
class ClassTest1
main
class java.lang.Object
wait
class java.lang.Object
wait
class java.lang.Object
wait
class java.lang.Object
hashCode
class java.lang.Object
getClass
class java.lang.Object
equals
class java.lang.Object
toString
class java.lang.Object
notify
class java.lang.Object
notifyAll
2.TestClass.java
[java] view plain
/**
*
*/
public class TestClass {
public static void main(String[] args)
{
try {
// 測試Class.forName()
Class testTypeForName = Class.forName("TestClassType");
System.out.println("testForName---" + testTypeForName);
// 測試類名.class
Class testTypeClass = TestClassType.class;
System.out.println("testTypeClass---" + testTypeClass);
// 測試Object.getClass()
TestClassType testGetClass = new TestClassType();
System.out.println("testGetClass---" + testGetClass.getClass());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TestClassType {
// 構造函數
public TestClassType() {
System.out.println("----構造函數---");
}
// 靜態的參數初始化
static {
System.out.println("---靜態的參數初始化---");
}
// 非靜態的參數初始化
{
System.out.println("----非靜態的參數初始化---");
}
}
運行結果:
[plain] view plain
---靜態的參數初始化---
testForName---class TestClassType
testTypeClass---class TestClassType
----非靜態的參數初始化---
----構造函數---
testGetClass---class TestClassType
分析:根據結果可以發現,三種生成的Class對象一樣的,並且三種生成Class對象只列印一次「靜態的參數初始化」。
5. 關於用java反射調用一個類裡面的方法並執行
Java中要用到反射,首先就必須要獲取到對應的class對象,在Java中有三種方法獲取類對應的class對象。
1、通過類的.class屬性
2、通過類實例的getClass()方法獲取
3、通過Class.forName(String className)方法獲取
現在比如在package下有個類Calculator
publicclassCalculator{
publicdoubleadd(doublescore1,doublescore2){
returnscore1+score2;
}
publicvoidprint(){
System.out.println("OK");
}
publicstaticdoublemul(doublescore1,doublescore2){
returnscore1*score2;
}
}
publicclassCalculatorTest{
publicstaticvoidmain(String[]args)throwsException{
//通過類的.class屬性獲取
Class<Calculator>clz=Calculator.class;
//或者通過類的完整路徑獲取,這個方法由於不能確定傳入的路徑是否正確,這個方法會拋ClassNotFoundException
// Class<Calculator>clz=Class.forName("test.Calculator");
//或者new一個實例,然後通過實例的getClass()方法獲取
// Calculators=newCalculator();
// Class<Calculator>clz=s.getClass();
//1.獲取類中帶有方法簽名的mul方法,getMethod第一個參數為方法名,第二個參數為mul的參數類型數組
Methodmethod=clz.getMethod("mul",newClass[]{double.class,double.class});
//invoke方法的第一個參數是被調用的對象,這里是靜態方法故為null,第二個參數為給將被調用的方法傳入的參數
Objectresult=method.invoke(null,newObject[]{2.0,2.5});
//如果方法mul是私有的private方法,按照上面的方法去調用則會產生異常NoSuchMethodException,這時必須改變其訪問屬性
//method.setAccessible(true);//私有的方法通過發射可以修改其訪問許可權
System.out.println(result);//結果為5.0
//2.獲取類中的非靜態方法
Methodmethod_2=clz.getMethod("add",newClass[]{double.class,double.class});
//這是實例方法必須在一個對象上執行
Objectresult_2=method_2.invoke(newCalculator(),newObject[]{2.0,2.5});
System.out.println(result_2);//4.5
//3.獲取沒有方法簽名的方法print
Methodmethod_3=clz.getMethod("print",newClass[]{});
Objectresult_3=method_3.invoke(newCalculator(),null);//result_3為null,該方法不返回結果
}
}
6. java 反射 調用無參數方法
通過Java反射調用無參數方法,這是個測試用的例子,通過反射調用對象的方法,代碼如下:
importjava.lang.reflect.Method;
importjava.lang.reflect.InvocationTargetException;
/**
*CreatedbyIntelliJIDEA.
*File:TestRef.java
*User:Administrator
*Date:2015-7-1016:28:44
*/
publicclassTestRef{
publicstaticvoidmain(Stringargs[])throwsNoSuchMethodException,IllegalAccessException,InvocationTargetException{
Foofoo=newFoo("這個一個Foo對象!");
Classclazz=foo.getClass();
Methodm1=clazz.getDeclaredMethod("outInfo");
Methodm2=clazz.getDeclaredMethod("setMsg",String.class);
Methodm3=clazz.getDeclaredMethod("getMsg");
m1.invoke(foo);
m2.invoke(foo,"重新設置msg信息!");
Stringmsg=(String)m3.invoke(foo);
System.out.println(msg);
}
}
classFoo{
privateStringmsg;
publicFoo(Stringmsg){
this.msg=msg;
}
publicvoidsetMsg(Stringmsg){
this.msg=msg;
}
publicStringgetMsg(){
returnmsg;
}
publicvoidoutInfo(){
System.out.println("這是測試Java反射調用無參數方法的測試類");
}
}
控制台輸出結果:
這是測試Java反射調用無參數方法的測試類
重新設置msg信息!
Processfinishedwithexitcode0
7. 如何通過java 反射 調用一個 含有 可變參數的 方法呢
java反射調用可變參數的方法的方式是傳入objects參數,如下代碼:
publicclassReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Single.class;
Singlesingle=(Single)clazz.newInstance();
List<String>list=newArrayList<String>(){
=1L;
{
add("fuck");
add("ni");
add("mei");
}
};
//獲取method兩種方式,在method中數組的的空間大小是可以隨便寫的不一定使用0
/*1*/
Methodmethod=clazz.getDeclaredMethod("method",Array.newInstance(Object.class,0).getClass());
/*2*/
method=clazz.getDeclaredMethod("method",(newObject[0]).getClass());//初始化參數
/*1*/
Objectobjs=Array.newInstance(Object.class,2);
Array.set(objs,0,list);
Array.set(objs,1,"23");
method.invoke(single,objs);
/*2*/
Object[]objects={1,"fuck",list};
method.invoke(single,newObject[]{objects});
}
}
classSingle{
publicvoidmethod(Object...objs){
System.out.println(Arrays.deepToString(objs));
}
}
結果:
[[fuck,ni,mei],23]
[1,fuck,[fuck,ni,mei]]
8. 如何通過反射調用有參構造函數
想通過反射調用有參構造函數,需要用到一個java類——Constructor。
Constructor提供關於類的單個構造方法的信息以及它的訪問許可權。
這我先建一個測試類。
package reflect;
import java.lang.reflect.Constructor;
class Person{
//兩個屬性
private String name;
private int age;
//假設有四種構造方法,一個無參構造方法,三個有參構造方法
public Person(){}
public Person(String name){
this.name=name;
}
public Person(int age){
this.age=age;
}
public Person(String name,Integer age){
this.name=name;
this.age=age;
}
@Overrride
public String toString(){
return "Person [age="+age+",name="+name+"]";
}
}
接下來主要說明怎麼通過反射調用有參構造函數。
要調用有參構造函數一般已經知道該構造函數的參數類型和參數列表長什麼樣子了。
要做的就是拿到它,並通過它初始化實例。
package reflect;
public class Test{
public static void main(String args[]){
Class<?> demo =null;
try{
//通過反射聲明Person
demo=Class.forName("reflect.Person");
}catch(Exception e){
e.printStackTrace();
}
//定義一個Person用來接收
Person per = null;
//關鍵來了---------------
Constructor<?> con=null; //聲明一個Constructor
Class[] paramTypes={String.class,Integer.class}; //你要使用的有參構造函數中參數列表中的各個類型。
try{
con=demo.getConstrucetor(paramTypes);//通過類型獲得構造方法的構造信息和訪問許可權
per=(Person)con.newInstance("Tom",20);//找到就可以使用了,傳參實例化。
}catch(Exception e){
e.printStackTrace();
}
//-----------------------
System.out.println(per);
}
}
輸出結果:Person [age=20,name=Tom]
9. JAVA反射中通過Class.forname()如何帶參數的方法怎麼賦值和調用呀
用Class.forName方法動態載入構造方法帶參數的類。
10. java中,用反射方式調用一個類中的main方法
Main方法是用static修飾的,有種方法可以調用
1.類名.main(參數);
2.new創建實例,實例.main(參數);
這個地方注意必須傳遞字元串數組的參數 或者 null !
另外舉一個用反射機制調用Main方法的例子
這個類是被調用的main方法類:
Java代碼
public class Run
{
public static void main(String[] args)
{
String str=args[0]+"Hello World";
System.out.println(str);
}
}
下面是調用main方法的類:
Java代碼
public class JobRun
{
public static void main(String[] args)
{
String idStr = "YAya";
try
{
Method method = Run.class.getMethod("main", String[].class);
method.invoke(null, (Object) new String[] { idStr });
}
catch (Exception e)
{
e.printStackTrace();
}
}
}