1. 程式人生 > >Java反射用法詳解

Java反射用法詳解

在過去的幾次面試中,都被問到了反射這塊的知識,並沒有系統瞭解過Java的反射機制(現實是幾乎怎麼接觸過),所以這方面的問題基本都回答不上來T_T

鎮定思痛,我們來一起好好看看Java中反射的用法。

關於反射的基本用法, http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html  已經有了比較全面的總結,例子也比較豐富,但是有些地方講的也不太對,而且對於內部類的反射並沒有講到。

在獲取多個構造器並用這個構造器建立新例項時用了這樣的例子:

package Reflect;
 
import java.lang.reflect.Constructor;
 
class Person{
     
    public Person() {
         
    }
    public Person(String name){
        this.name=name;
    }
    public Person(int age){
        this.age=age;
    }
    public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    @Override
    public String toString(){
        return "["+this.name+"  "+this.age+"]";
    }
    private String name;
    private int age;
}
 
class hello{
    public static void main(String[] args) {
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch (Exception e) {
            e.printStackTrace();
        }
        Person per1=null;
        Person per2=null;
        Person per3=null;
        Person per4=null;
        //取得全部的建構函式
        Constructor<?> cons[]=demo.getConstructors();
        try{
            per1=(Person)cons[0].newInstance();
            per2=(Person)cons[1].newInstance("Rollen");
            per3=(Person)cons[2].newInstance(20);
            per4=(Person)cons[3].newInstance("Rollen",20);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println(per1);
        System.out.println(per2);
        System.out.println(per3);
        System.out.println(per4);
    }
}
然而我執行這個程式會得到一個Exception:

這是由於獲取到的構造器的順序和原來類中定義的順序不一樣造成的。

在我的機器上,必須按照如下構造器的順序才能正常新建例項:

在查閱了一些資料後我瞭解到JDK對於這個順序並沒有作要求,使用不同版本的JDK獲取的構造器順序可能會有不同,我們寫程式的時候不應該依賴這個順序。

正確的做法是在Class上呼叫帶引數列表的getConstructor()方法來獲取對應的Constructor,再使用這個Constructor來生成新例項。

例如:

            Constructor cons0 = demo.getConstructor();
            Constructor cons1 = demo.getConstructor(String.class);
            Constructor cons2 = demo.getConstructor(int.class);
            Constructor cons3 = demo.getConstructor(String.class,int.class);
             
            Person per1 = (Person) cons0.newInstance();
            Person per2 = (Person) cons1.newInstance("Rollen");
            Person per3 = (Person) cons2.newInstance(20);
            Person per4 = (Person) cons3.newInstance("Rollen", 20);

最後是獲取內部類私有成員變數和方法的例子:

package Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class InnerClassTest {

	public InnerClassTest() {

	}

	public InnerClassTest(String str) {

	}

	class Inner {
		private String name = "Inner";

		public Inner() {
		}

		public Inner(String na) {
			name = na;
		}
		
		private int get(int value){
			return value;
		}
		
		@Override
		public String toString() {
			// TODO Auto-generated method stub
			return "InnerClass : " + name;
		}
	}

	public static void main(String args[]) {
		try {
			Class c = Class.forName("Reflect.InnerClassTest$Inner");
			if (c != null) {
				Constructor con = c.getDeclaredConstructor(InnerClassTest.class,String.class);
				System.out.println(con.newInstance(new InnerClassTest(),"hello"));
				Method me = c.getDeclaredMethod("get",int.class);
				me.setAccessible(true);
				System.out.println(me.invoke(new InnerClassTest().new Inner(),20));
				Field fe = c.getDeclaredField("name");
				fe.setAccessible(true);
				System.out.println(fe.get(new InnerClassTest().new Inner()));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

(非靜態的)內部類的構造方法獲取時比較不一樣,需要傳入外部類物件,同時,在通過獲取的構造器建立例項的時候也需要傳入外部類的例項。

對於靜態的物件和方法,對其呼叫get()或者invoke()方法時第一個引數將會被忽略,我們直接傳入空物件null就可以了。


相關推薦

Java反射用法

在過去的幾次面試中,都被問到了反射這塊的知識,並沒有系統瞭解過Java的反射機制(現實是幾乎怎麼接觸過),所以這方面的問題基本都回答不上來T_T 鎮定思痛,我們來一起好好看看Java中反射的用法。 關於反射的基本用法, http://www.cnblogs.com/roll

Java反射機制

java 反射 反射機制 工廠模式 1反射機制是什麽反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。在面向對象的世界裏,萬事萬物皆對象.在ja

Java反射機制

ride length 數組大小 conf array arraycopy 動態調用 ray info Java反射機制詳解 |目錄 1反射機制是什麽 2反射機制能做什麽 3反射機制的相關API ·通過一個對象獲得完整的包名和類名 ·實例化Class類對象 ·獲

Java反射機制(由淺入深)

一、什麼是Java反射機制? Java 反射機制在程式執行時,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。這種 動態的獲取資訊 以及 動態呼叫物件的方法 的功能稱為 java 的反

Java 反射機制(一)

Java 反射機制詳解(一) 主要介紹以下幾方面內容 理解 Class 類 理解 Java 的類載入機制 學會使用 ClassLoader 進行類載入 理解反射的機制 掌握 Constructor、Method、Field 類的用法 理解並掌握動態代理&n

Java 反射機制(四)

Java 反射機制詳解(四) 4. 反射與泛型  定義一個泛型類: public class DAO<T> { //根據id獲取一個物件 T get(Integer id){ return null; }

JAVA反射基礎

1.步入正題之前先扯會淡         之前,在論壇看到別人說過這樣一句話:“用專有名詞去解釋專有名詞其實就是一件扯淡的事兒” 。 其實我覺得不無道理,好多技術文件都是用專有名詞去解釋專有名詞,我在看其他博主或者技術文件時也要同時google著裡面不理解的一些專有名詞。

java反射機制(二)

主要介紹以下幾方面內容 理解 Class 類 理解 Java 的類載入機制 學會使用 ClassLoader 進行類載入 理解反射的機制 掌握 Constructor、Method、Field 類的用法 理解並掌握動態代理 1.理解Class類  

JAVA反射例項與介紹

我們都知道Java反射很重要,這次我來拋個磚頭!!! 一:反射    反射是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。   使用java的反射,一般有下面三步:     1:獲得你想操作類

java反射例子

1、通過一個物件獲得完整的包名和類名 Java程式碼   package Reflect;  /**  * 通過一個物件獲得完整的包名和類名  * */class Demo{      //other codes...}  class hello{      publ

java反射例項

本文先講java反射的示例程式碼,希望看了程式碼以及分析對你有所幫助。  【案例1】通過一個物件獲得完整的包名和類名 package org.shen.own;  import java.util.Enumeration; 

java wait用法

一、wait(), notify(), notifyAll()等方法介紹 1.wait()的作用是讓當前執行緒進入等待狀態,同時,wait()也會讓當前執行緒釋放它所持有的鎖。“直到其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法”,當前執行緒

java反射機制和應用

1反射機制是什麼 反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。 2反射機制能做什麼 反射機制主要提供了以下功能: 在執行

java Socket用法

     在客戶/伺服器通訊模式中, 客戶端需要主動建立與伺服器連線的 Socket(套接字), 伺服器端收到了客戶端的連線請求, 也會建立與客戶連線的 Socket. Socket可看做是通訊連線兩端的收發器, 伺服器與客戶端都通過 Socket 來收發資料. 這篇文章首

Java反射完全

三、反射的使用 3.1獲取Class物件的三種方式。 3.1測試類: public class Example1 { public static void main(String[] args) { // 1.第一種方式獲取Class物件

Java反射機制 及 Method.invoke解釋

JAVA反射機制 JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。 Java反射機制主要提供了以下功能: 在執行時判

Java Scanner用法

本文轉載自: 一、Scanner類簡介       Java 5添加了java.util.Scanner類,這是一個用於掃描輸入文字的新的實用程式。它是以前的StringTokenizer和Matcher類之間的某種結合。由於任何資料都必須通過同一模式的捕獲組檢索或

java BigDecimal用法(保留小數,四捨五入,數字格式化,科學計數法轉數字等)

一、簡介    Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變數double可以處理16位有效數。在實際應用中,需要對更大或者更小的數進行運算和處理。float和double只能用來做科學計算或者是

Java反射機制 及 Method.invoke 解釋

Java反射機制 Java反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為:Java語言的反射機制。 Java反射機制主要提供以下幾個功能:

JAVA反射呼叫

JAVA反射呼叫的確是一種很神奇的機制,在專案中使用後戀戀不忘,現將其好好整理一下。 反射機制概述 反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。 這種動態獲取