1. 程式人生 > >對於JAVA反射機制和CLASS類的個人理解

對於JAVA反射機制和CLASS類的個人理解

上週上課老師點我起來回答問題,問了一下JAVA反射機制,我本來對JAVA用得不多,加上有一段時間沒有看過了,所以並沒有能夠答出來,之後就想要好好理解理解,加上老師佈置作業讓弄懂JAVA反射和Class類,所以CSDN第一次寫部落格,就來寫寫我對反射和Class的學習之後的感受吧。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

一.什麼是JAVA的反射機制。

JAVA反射是指在程式執行時獲取已知名稱的類或已有物件的相關資訊的一種機制。簡單說來,就是可以在程式執行過程中得到剛剛知道的一個類的內部結構。就像老師所說的,反射是和動態掛鉤的,反射就意味著我們可以動態地獲取資訊,動態地呼叫,建立物件。

在這裡還是先給出一個簡單的例子讓大家稍微熟悉一下。也方便接下來Class的學習。

import java.util.Scanner;

import java.lang.reflect.Method;

public class ClassForName {

   public ClassForName(){
  
      try {
    	 Scanner inScanner = new Scanner(System.in);
    	  
         Class<?> classinstance=Class.forName(inScanner.next());  //根據輸入返回一個類物件

         Method[] method=classinstance.getDeclaredMethods();//利用得到的Class物件,返回該類物件的方法集合
        
         System.out.println("forName:"+classinstance);
         
         for(Method me:method){
        	 
            System.out.println("方法有:"+me.toString());
            
         }//輸出所有方法的名稱
         
      }catch (ClassNotFoundException e) {
    	  
         e.printStackTrace();
      }

   }
   
   public static void main(String[] args) {
	   
      new ClassForName();
      
   }
}

這裡給出這個例子的輸出,當我輸入java.lang.Class時,返回所有方法,輸出為:

方法有:private java.lang.Object java.lang.Class.newInstance0() throws java.lang.InstantiationException,java.lang.IllegalAccessException

方法有:public static java.lang.Class java.lang.Class.forName(java.lang.String,boolean,java.lang.ClassLoader) throws java.lang.ClassNotFoundException
方法有:public static java.lang.Class java.lang.Class.forName(java.lang.String) throws java.lang.ClassNotFoundException
方法有:private static native java.lang.Class java.lang.Class.forName0(java.lang.String,boolean,java.lang.ClassLoader) throws java.lang.ClassNotFoundException

方法有:public native boolean java.lang.Class.isAssignableFrom(java.lang.Class)
方法有:public native boolean java.lang.Class.isInstance(java.lang.Object)
方法有:public native int java.lang.Class.getModifiers()
方法有:public native boolean java.lang.Class.isInterface()
方法有:public native boolean java.lang.Class.isArray()
方法有:public native boolean java.lang.Class.isPrimitive()
方法有:public native java.lang.Class java.lang.Class.getSuperclass()
方法有:public native java.lang.Class java.lang.Class.getComponentType()

方法有:private static native void java.lang.Class.registerNatives()
方法有:public java.lang.String java.lang.Class.toString()
方法有:public java.lang.String java.lang.Class.getName()
方法有:static boolean java.lang.Class.access$100(java.lang.Object[],java.lang.Object[])
方法有:static boolean java.lang.Class.access$202(boolean)
方法有:static boolean java.lang.Class.access$302(boolean)
方法有:private static void java.lang.Class.addAll(java.util.Collection,java.lang.reflect.Field[])
方法有:private static java.lang.String java.lang.Class.argumentTypesToString(java.lang.Class[])
方法有:private static boolean java.lang.Class.arrayContentsEq(java.lang.Object[],java.lang.Object[])
方法有:public java.lang.Class java.lang.Class.asSubclass(java.lang.Class)
方法有:public java.lang.Object java.lang.Class.cast(java.lang.Object)
方法有:private static void java.lang.Class.checkInitted()
方法有:private void java.lang.Class.checkMemberAccess(int,java.lang.ClassLoader)
方法有:private void java.lang.Class.clearCachesOnClassRedefinition()
方法有:private static java.lang.reflect.Constructor[] java.lang.Class.copyConstructors(java.lang.reflect.Constructor[])
方法有:private static java.lang.reflect.Field[] java.lang.Class.copyFields(java.lang.reflect.Field[])
方法有:private static java.lang.reflect.Method[] java.lang.Class.copyMethods(java.lang.reflect.Method[])
方法有:public boolean java.lang.Class.desiredAssertionStatus()
方法有:private static native boolean java.lang.Class.desiredAssertionStatus0(java.lang.Class)
方法有:java.util.Map java.lang.Class.enumConstantDirectory()
方法有:public java.lang.annotation.Annotation java.lang.Class.getAnnotation(java.lang.Class)
方法有:sun.reflect.annotation.AnnotationType java.lang.Class.getAnnotationType()
方法有:public java.lang.annotation.Annotation[] java.lang.Class.getAnnotations()
方法有:public java.lang.String java.lang.Class.getCanonicalName()
方法有:public java.lang.ClassLoader java.lang.Class.getClassLoader()
方法有:native java.lang.ClassLoader java.lang.Class.getClassLoader0()
方法有:public java.lang.Class[] java.lang.Class.getClasses()
方法有:native sun.reflect.ConstantPool java.lang.Class.getConstantPool()
方法有:public java.lang.reflect.Constructor java.lang.Class.getConstructor(java.lang.Class[]) throws java.lang.NoSuchMethodException,java.lang.SecurityException
方法有:private java.lang.reflect.Constructor java.lang.Class.getConstructor0(java.lang.Class[],int) throws java.lang.NoSuchMethodException
方法有:public java.lang.reflect.Constructor[] java.lang.Class.getConstructors() throws java.lang.SecurityException
方法有:public java.lang.annotation.Annotation[] java.lang.Class.getDeclaredAnnotations()
方法有:public java.lang.Class[] java.lang.Class.getDeclaredClasses() throws java.lang.SecurityException
方法有:private native java.lang.Class[] java.lang.Class.getDeclaredClasses0()
方法有:public java.lang.reflect.Constructor java.lang.Class.getDeclaredConstructor(java.lang.Class[]) throws java.lang.NoSuchMethodException,java.lang.SecurityException
方法有:public java.lang.reflect.Constructor[] java.lang.Class.getDeclaredConstructors() throws java.lang.SecurityException
方法有:private native java.lang.reflect.Constructor[] java.lang.Class.getDeclaredConstructors0(boolean)
方法有:public java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String) throws java.lang.NoSuchFieldException,java.lang.SecurityException
方法有:public java.lang.reflect.Field[] java.lang.Class.getDeclaredFields() throws java.lang.SecurityException
方法有:private native java.lang.reflect.Field[] java.lang.Class.getDeclaredFields0(boolean)
方法有:public java.lang.reflect.Method java.lang.Class.getDeclaredMethod(java.lang.String,java.lang.Class[]) throws java.lang.NoSuchMethodException,java.lang.SecurityException
方法有:public java.lang.reflect.Method[] java.lang.Class.getDeclaredMethods() throws java.lang.SecurityException
方法有:private native java.lang.reflect.Method[] java.lang.Class.getDeclaredMethods0(boolean)
方法有:public native java.lang.Class java.lang.Class.getDeclaringClass()
方法有:public java.lang.Class java.lang.Class.getEnclosingClass()
方法有:public java.lang.reflect.Constructor java.lang.Class.getEnclosingConstructor()
方法有:public java.lang.reflect.Method java.lang.Class.getEnclosingMethod()
方法有:private native java.lang.Object[] java.lang.Class.getEnclosingMethod0()
方法有:private java.lang.Class$EnclosingMethodInfo java.lang.Class.getEnclosingMethodInfo()
方法有:public java.lang.Object[] java.lang.Class.getEnumConstants()
方法有:java.lang.Object[] java.lang.Class.getEnumConstantsShared()
方法有:private sun.reflect.generics.factory.GenericsFactory java.lang.Class.getFactory()
方法有:public java.lang.reflect.Field java.lang.Class.getField(java.lang.String) throws java.lang.NoSuchFieldException,java.lang.SecurityException
方法有:private java.lang.reflect.Field java.lang.Class.getField0(java.lang.String) throws java.lang.NoSuchFieldException
方法有:public java.lang.reflect.Field[] java.lang.Class.getFields() throws java.lang.SecurityException
方法有:private sun.reflect.generics.repository.ClassRepository java.lang.Class.getGenericInfo()
方法有:public java.lang.reflect.Type[] java.lang.Class.getGenericInterfaces()
方法有:private native java.lang.String java.lang.Class.getGenericSignature()
方法有:public java.lang.reflect.Type java.lang.Class.getGenericSuperclass()
方法有:public native java.lang.Class[] java.lang.Class.getInterfaces()
方法有:public java.lang.reflect.Method java.lang.Class.getMethod(java.lang.String,java.lang.Class[]) throws java.lang.NoSuchMethodException,java.lang.SecurityException
方法有:private java.lang.reflect.Method java.lang.Class.getMethod0(java.lang.String,java.lang.Class[])
方法有:public java.lang.reflect.Method[] java.lang.Class.getMethods() throws java.lang.SecurityException
方法有:private native java.lang.String java.lang.Class.getName0()
方法有:public java.lang.Package java.lang.Class.getPackage()
方法有:static native java.lang.Class java.lang.Class.getPrimitiveClass(java.lang.String)
方法有:public java.security.ProtectionDomain java.lang.Class.getProtectionDomain()
方法有:private native java.security.ProtectionDomain java.lang.Class.getProtectionDomain0()
方法有:private native byte[] java.lang.Class.getRawAnnotations()
方法有:private static sun.reflect.ReflectionFactory java.lang.Class.getReflectionFactory()
方法有:public java.net.URL java.lang.Class.getResource(java.lang.String)
方法有:public java.io.InputStream java.lang.Class.getResourceAsStream(java.lang.String)
方法有:public native java.lang.Object[] java.lang.Class.getSigners()
方法有:private java.lang.String java.lang.Class.getSimpleBinaryName()
方法有:public java.lang.String java.lang.Class.getSimpleName()
方法有:public java.lang.reflect.TypeVariable[] java.lang.Class.getTypeParameters()
方法有:private synchronized void java.lang.Class.initAnnotationsIfNecessary()
方法有:public boolean java.lang.Class.isAnnotation()
方法有:public boolean java.lang.Class.isAnnotationPresent(java.lang.Class)
方法有:public boolean java.lang.Class.isAnonymousClass()
方法有:private static boolean java.lang.Class.isAsciiDigit(char)
方法有:public boolean java.lang.Class.isEnum()
方法有:public boolean java.lang.Class.isLocalClass()
方法有:private boolean java.lang.Class.isLocalOrAnonymousClass()
方法有:public boolean java.lang.Class.isMemberClass()
方法有:public boolean java.lang.Class.isSynthetic()
方法有:public java.lang.Object java.lang.Class.newInstance() throws java.lang.InstantiationException,java.lang.IllegalAccessException
方法有:private java.lang.reflect.Constructor[] java.lang.Class.privateGetDeclaredConstructors(boolean)
方法有:private java.lang.reflect.Field[] java.lang.Class.privateGetDeclaredFields(boolean)
方法有:private java.lang.reflect.Method[] java.lang.Class.privateGetDeclaredMethods(boolean)
方法有:private java.lang.reflect.Field[] java.lang.Class.privateGetPublicFields(java.util.Set)
方法有:private java.lang.reflect.Method[] java.lang.Class.privateGetPublicMethods()
方法有:private java.lang.String java.lang.Class.resolveName(java.lang.String)
方法有:private java.lang.reflect.Field java.lang.Class.searchFields(java.lang.reflect.Field[],java.lang.String)
方法有:private static java.lang.reflect.Method java.lang.Class.searchMethods(java.lang.reflect.Method[],java.lang.String,java.lang.Class[])
方法有:void java.lang.Class.setAnnotationType(sun.reflect.annotation.AnnotationType)
方法有:native void java.lang.Class.setProtectionDomain0(java.security.ProtectionDomain)
方法有:native void java.lang.Class.setSigners(java.lang.Object[])
方法有:private static java.lang.Class java.lang.Class.toClass(java.lang.reflect.Type)

跟官方文件給出的方法一樣,這裡我們將Class的所有方法列舉了出來,這恰恰體現反射中的動態獲取資訊。  ps.在這裡,將比較重要的方法加黑標記出來。

二.反射的重要“嘉賓”--Class類解讀

上面我們用一個小例子,列舉除了Class類的方法,下面是時候來好好分析分析Class類了,首先Class類沒有公共的構造方法,它的物件是在載入類的時候由java虛擬機器以及通過呼叫類載入器中的defineClass方法自動構造的,虛擬機器為每一種型別都生成管理著一個Class物件。說白了,Class類就是一個大的模板,每一種具體的型別載入的時候,JVM都會生成一個相對應的Class物件來負責獲取這一型別的所有內部資訊。  這讓我想到了一個小例子,Class就把它看作是一個模具,每一個空缺的不同圖案都是型別中的一個部分,或是方法,或是屬性,每當載入一個具體的型別的時候,往模具上一拍,就能夠去得到所有想要的資訊。

感覺這已經很白話文了,這個具體的過程在我看來就是這樣,假如有錯誤的地方,歡迎批評指正。

在這之後,我先說說如何去生成Class物件,然後再挑選幾個比較重要的方法談談理解。

如何生成Class物件

首先,老師給的方法是用到了Class類裡面的靜態方法forName()。

Class c =Class.forName("String");
Object obj = c.newInstance();
return obj;

其次,第二種方法,通過Object類中的getClass()方法來得到Class物件。
String s;
Class c = s.getClass();

第三種,就是直接用已經存在的類名去生成。
Class c1 = String.class;
Class c2 = double [] .class;

Class類中的方法

     public static Class<?> forName(String className)

Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:

Class.forName(className, true, currentLoader)
where currentLoader denotes the defining class loader of the current class.


For example:

Class t = Class.forName("java.lang.Thread")
A call to forName("X") causes the class named X to be initialized.

public T newInstance()

Creates a new instance of the class represented by this Class object.

Returns:
a newly allocated instance of the class represented by this object.

public ClassLoader getClassLoader()

Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. 

Returns:
the class loader that loaded the class or interface represented by this object.

public String getName()

Returns the name of the entity (class, interface, array class, primitive type, or void) represented by this Class object, as a String.

public T cast(Object obj)

Casts an object to the class or interface represented by this Class object.

Returns:
the object after casting, or null if obj is null

三.小結與例項

最後寫了一個工廠模式的例項,也算是重新好好地梳理了一下反射機制,作為對反射機制的總結。

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import java.io.*;
public class TVFactory
{
	public static void main(String args[])
	{
         try
         {
         	TV tv;
         	TvFactory factory;
         	factory=(TvFactory)XMLUtil.getBean();
         	tv=factory.produceTV();
         	tv.play();
         }
         catch(Exception e)
         {
         	System.out.println(e.getMessage());
         }
	}
}
class HaierTV implements TV
{
	public void play()
	{
		System.out.println("海爾電視機播放中......");
	}
}
class HaierTVFactory implements TvFactory
{
    public TV produceTV()
    {
    	System.out.println("海爾電視機工廠生產海爾電視機。");
    	return new HaierTV();
    }
}
class HisenseTV implements TV
{
	public void play()
	{
		System.out.println("海信電視機播放中......");
	}	
}
class HisenseTVFactory implements TvFactory
{
    public TV produceTV()
    {
    	System.out.println("海信電視機工廠生產海信電視機。");
    	return new HisenseTV();
    }
}
interface TV
{
	public void play();
}
interface TvFactory
{
    public TV produceTV();
}
class XMLUtil
{
	public static Object getBean()
	{
		try
		{
			DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = dFactory.newDocumentBuilder();
			Document doc;							
			doc = builder.parse(new File("config.xml")); 

			NodeList nl = doc.getElementsByTagName("className");
            <span style="white-space:pre">		</span>Node classNode=nl.item(0).getFirstChild();
          <span style="white-space:pre">		</span>String cName=classNode.getNodeValue();
            

           <span style="white-space:pre">		</span>Class c=Class.forName(cName);
	  	   <span style="white-space:pre">	</span>Object obj=c.newInstance();
            <span style="white-space:pre">		</span>return obj;
           <span style="white-space:pre">	</span>}   
           	catch(Exception e)
           	{
           		e.printStackTrace();
           		return null;
           	}
	}
}

歡迎批評指正       email:[email protected]

相關推薦

對於JAVA反射機制CLASS個人理解

上週上課老師點我起來回答問題,問了一下JAVA反射機制,我本來對JAVA用得不多,加上有一段時間沒有看過了,所以並沒有能夠答出來,之後就想要好好理解理解,加上老師佈置作業讓弄懂JAVA反射和Class類,所以CSDN第一次寫部落格,就來寫寫我對反射和Class的學習之後的感

java反射機制Class

面向物件思想 一切皆物件 類也是物件,Class類的物件,java.lang.Class Class類的構造器是私有的,只有虛擬機器可以直接建立它的物件, 有三種建立方式:類.class、類物件.getClass、Class.forName 靜態載入:new,發生在編譯的時候 動態載

Java反射機制Class.forName、例項物件.class(屬性)、例項物件getClass()的區別

二、Class.forName、例項物件.class(屬性)、例項物件getClass()的區別 1、相同點: 通過這幾種方式,得到的都是Java.lang.Class物件(這個是上面講到的 類在載入時獲得的最終產物) 例如: package demo;public class A{ public st

Java反射機制獲取/呼叫的屬性方法

      Java反射機制主要提供了以下功能: 在執行時判斷任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判斷任意一個類所具有的成員變數和方法;在執行時呼叫任意一個物件的方法;生成動態代理。 public class Message { public

JAVA的newInstance()new的區別(JAVA反射機制,通過名來獲取該類的例項化物件)

newInstance()是實現IOC、反射、面對介面程式設計 和 依賴倒置 等技術方法的必然選擇,new 只能實現具體類的例項化,不適合於介面程式設計。 裡面就是通過這個類的預設建構函式構建了一個物件,如果沒有預設建構函式就丟擲InstantiationException, 如果沒有訪問預設建構函式的許可權

反射機制Class

  從這節課開始, 我們正式進入java 反射機制的學習     首先,什麼是java的反射機制?來看百度百科: 重點: 在執行狀態中 對任意一個實體類 對任意一個物件 動態獲取資訊 動態呼叫物件方法 &

java反射機制,註解解讀

1.元資料的英文關於資料的組織,域資料及其關係的資訊,簡言之,元資料就是關於資料的資料(英文:間位),不同的領域有不同的理解:在軟體構造領域,元資料被定義為:。在程式中不是被加工的物件,而是通過其值的改變來改變程式的行為的資料它在執行過程中起著以解釋方式控制程式行為的作用在程

Java 反射的源頭Class

Java 反射的源頭Class類 1. Class類 2.Class類常用方法 3. 反射Class的理解 3.1. java.lang.Class:是反射的源頭 3.2.反射的理解 4.Do

Java 反射機制動態代理是基於什麼原理,瞭解過嗎?

工作多年以及在面試中,我經常能體會到,有些面試者確實是認真努力工作,但坦白說表現出的能力水平卻不足以通過面試,通常是兩方面原因: 1、“知其然不知其所以然”。 做了多年技術,開發了很多業務應用,但似乎並未思考過種種技術選擇背後的邏輯。坦白說,我並不放心把具有一定深度的任務交給他。 2、

非深入探尋Java反射機制Class

Classes 通過反射機制我們可以在執行時探尋類的內部結構,並獲取以下資訊 Class NameClass Modifiers (public, protected, synchronized等)Package InfoSuper ClassImplemented In

深入理解java反射機制中Method中的invoke()方法

1.先說明Method類中的幾個重要的屬性 1)Method型別的root屬性: 可以理解為每一個 java方法都有唯一的一個Method物件,這個物件就是root,我們可以利用反射建立java方法的眾多的Method類的物件,這些物件指向root,可以理解為root的映象

JAVA反射機制CLASS.FORNAME的作用及含義

最近由於工作上需要,對reflection做了一番瞭解,以下是學習總結,有不少內容是借鑑的,但已無法找到源文出處,還請原文作者見諒。 Reflection 是Java被視為動態(或準動態)語言的一個關鍵性質。這個機制允許程式在執行時透過Reflection APIs取得任

Java中的載入Class.forName();java反射機制與原理

對於大部分人來說,第一次見到class.forName(String className)這句程式碼應該是在使用jdbc方式連線資料庫的時候。但這句程式碼本質上是什麼含義,做了什麼工作呢?本文將回答此問題。 理解Class.forName方法需要一些知識鋪墊,也就是

Class物件Java反射機制

一 前言 很多書上都說,在java的世界裡,一切皆物件。其實從某種意義上說,在java中有兩種物件:例項物件和Class物件。例項物件就是我們平常定義的一個類的例項: /** * Created by aristark on 3/28/16. */ public class Person

java反射(9)泛型Class

在不適用泛型的時候,必須將利用反射得到的物件進行強制轉換才可以對他進行相應的賦值,如下 package Chapter_6; import java.util.Date; public class YeekuObjectFactory { public stat

通過java反射機制,獲取物件的屬性值(包括所有繼承的父

      java的反射機制提供了兩種方法:    getDeclaredFields() :該方法能獲取到本類的所有屬性,包括private,protected和public,但不能獲取到繼承的父類的屬性。    getFields():既能獲取本類的屬性也能得到父類的

利用java反射機制一次性呼叫實體getset方法,簡化更多程式碼。

外部呼叫getProperty方法時只需要傳入實體物件即可;例如TestUtil.getProperty(new User()); 外部呼叫setProperty方法時只需要傳入實體物件和要set的值即可;例如TestUtil.setProperty(new User()

java 反射機制 之 getMethods獲取所有公有方法 getDeclaredMethods 獲取本所有方法

檔案結構: Person: package demo2; public class Person { private int age; private String name; public Person( String name,int ag

利用java反射機制,實現對的私有變數私有方法的訪問

記得有一句很有名的話:No reflection ,no frameworks 這一句短短的話道出了java 反射機制的強大。 java關於反射機制的包主要在java.lang.reflect中,structs,hibernate,spring等框架都是基於java的反射機制。 下面是一個關於利用j

通過java反射機制,獲取對象的屬性值(包括所有繼承的父

原創 getc getname 因此 declared protect 版權 str 來源 java的反射機制提供了兩種方法: getDeclaredFields() :該方法能獲取到本類的所有屬性,包括private,protected和public,但不能獲取到