日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java反射基础(一)--Class对象获取

發布時間:2024/7/23 java 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java反射基础(一)--Class对象获取 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Classes

?

??????? Java中,任何一個對象要么是一個引用類型要么是基本數據類型.引用類型指的是那些直接或間接

??? Java.lang.Object的類.Classse,enum,和接口都是應用類型.基本類型是一個固定的集合,它包括:

??? boolean,? byte,short, int, long,char,float, double. java.lang.String和所有的基本類型的

??? 包裹類(Wrapper classes),比如java.lang.Double,接口java.io.Serializabl,和枚舉

??? Jvax.swing.SortOrder都是引用類型.

?????? 對于每種類型的對象,java虛擬機都會為其初始化一個不變的java.lang.Class實例.這個實例提供了可以在運

????行時檢查對象屬性的方法.Class對象還具有創建一個新對象的能力.最重要的是,它是所有java發射的入口.

?

???? 1.獲取Class對象

???????? Java.lang.reflect包下的所有類都沒有公共的構造函數.要得到Class對象,,需要調用Class類中的適當的方法。

???? 有幾種法可以得到一個Class對象:

?

?????a.使用Object.getClass()

???????? 果已經有一個要反射的;類的實例,那么最簡單的方法去獲得該類的Class對象便是使用Object.getClass()方法.

?????然而這個方法只適用于要反射的類是引用類型.給出一些示例進行說明:

?

<span style="font-family:SimHei;font-size:14px;">Class c = "string".getClass(); 返回String類的Class對象 enum E { A, B }Class c = A.getClass(); A是一個枚舉類型,因此getClass(),返回枚舉類型E的Class對象. byte[] bytes = new byte[1024]; Class c = bytes.getClass(); 因為數組也是Objects,因此可以對數組調用getClass(), 該示例返回的是byte的Class對象. import java.util.HashSet; import java.util.Set; Set<String> s = new HashSet<String>(); Class c = s.getClass(); 在這個示例中,java.util.Set是一個接口,而java.util.HashSet實現了這個借口,那么getClass()返回的Class對象是java.util.HashSet的Class對象.</span>


?


? ??? b.使用.class 語法

?????????? 如果你只知道這個類型,但是卻沒辦法得到這個類型的一個實例,那么獲得該類型的Class對象的一種方法便

?????? 是使用.class.同時這也是最簡單的獲得基本類型得Class實例的方法.下面給出一些示例進行說明:

?

<span style="font-size:14px;"><span style="font-family:SimHei;">boolean b; Class c = b.getClass(); // compile-time errorClass c = boolean.class; // correct 語句boolean.getClass()將會產生一個編譯時錯誤,因為Boolean是一個基本數據類型,不能使用該方法獲取Class對象. Class c = java.io.PrintStream.class;Class c = int[][][].class; </span> </span>
??????? c.Class.forName()

???????????如果你知道一個class文件的完全名稱,你可以使用Class類中的靜態方法Class.forName()獲取類的Class對象.??????

<span style="font-family:SimHei;font-size:14px;">Class c = Class.forName("com.duke.MyLocaleServiceProvider");這條語句將會創建一個Class實例使用參數中指定的類.Class cDoubleArray = Class.forName("[D");Class cStringArray = Class.forName("[[Ljava.lang.String;"); 變量cDoubleArray將包含一個基本類型Double的Class實例,該語句等價于double[].class 變量CStringArray中包含了一個對應于兩個維度的String數組的Class對象.該語句等價于String[][].class </span>


?

?????? d.基本類型包裹類的TYPE屬性

??????????? .class語法是一個很方便的獲得基本類型的class對象的方法,然而還有另外一種方法可以獲得基本

??????? 類型的Class對象.所有的基本類型和void都有一個包裹類在java.lang包中.這些類將基本類型封裝起來

??????? 形成了一個引用類型.同時每個包裹類都包含了一個屬性叫做TYPE.TYPE等同于基本類型的Class對象.

<span style="font-family:SimHei;font-size:14px;">Class c = Double.TYPE;Class c = Void.TYPE; </span>

?

??????? e.返回類型是Class對象的方法

??????????? 有一些反射API方法可以返回Class對象,但是你想要使用這些方法你需要已經直接或者間接的得到了

??????? class對象.給出示例進行說明:

<span style="font-family:SimHei;font-size:14px;">Class.getSuperclass() 返回該類的父類的class對象.Class c = javax.swing.JButton.class.getSuperclass();javax.swing.JButton 的父類是 javax.swing.AbstractButton.</span>


?

Class.getClasses()? 返回該類的成員,包括所有公共類,接口,枚舉和繼承的成員.
<span style="font-family:SimHei;font-size:14px;">Class<?>[] c = Character.class.getClasses();Character 中包含兩個類 Character.Subset,Character.UnicodeBlock.</span>

?
Class.getDeclaredClasses()?返回所有該類中所有顯示聲明的接口和枚舉
<span style="font-family:SimHei;font-size:14px;">Class<?>[] c = Character.class.getDeclaredClasses();Character 包含兩個公共類Character.Subset 和 Character.UnicodeBlock 和一個私有的類Character.CharacterCache </span>
?
Class.getDeclaringClass()
????????????????????? java.lang.reflect.Field.getDeclaringClass()
????????????????????? java.lang.reflect.Method.getDeclaringClass()
????????????????????? java.lang.reflect.Constructor.getDeclaringClass()?????? 返回定義該成員的類的Class實例.

?

<span style="font-family:SimHei;font-size:14px;">import java.lang.reflect.Field;Field f = System.class.getField("out"); Class c = f.getDeclaringClass(); </span>


?

??? 2.獲取類的修飾符和類型?

??? 一個類可以有一個或者多個控制符??????

<span style="font-size:14px;"><span style="font-family:SimHei;"> 訪問控制符:<span>?</span><code style="FONT-FAMILY: Monaco,Courier,'Courier New'">public</code>,<span>?</span><code style="FONT-FAMILY: Monaco,Courier,'Courier New'">protected</code>, and<span>?</span><code style="FONT-FAMILY: Monaco,Courier,'Courier New'">private</code></span></span>
  • 需要重寫控制符:?abstract
  • 限定一個實例控制符:static
  • 禁止修改控制符:?final
  • 迫使嚴格浮點控制符:?strictfp
  • 注解

???ClassDeclarationSpy 演示了如何獲取一個類的聲明的組件,包括該類的修飾符,泛型參數,實現的接口,和繼承路徑.

???如果你實現了?java.lang.reflect.AnnotatedElement?,就可以獲取運行時注解.

<span style="font-family:SimHei;font-size:14px;">import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.Arrays; import java.util.ArrayList; import java.util.List; import static java.lang.System.out;public class ClassDeclarationSpy {public static void main(String... args) {try {Class<?> c = Class.forName(args[0]);out.format("Class:%n %s%n%n", c.getCanonicalName());out.format("Modifiers:%n %s%n%n",Modifier.toString(c.getModifiers()));out.format("Type Parameters:%n");TypeVariable[] tv = c.getTypeParameters();if (tv.length != 0) {out.format(" ");for (TypeVariable t : tv)out.format("%s ", t.getName());out.format("%n%n");} else {out.format(" -- No Type Parameters --%n%n");}out.format("Implemented Interfaces:%n");Type[] intfs = c.getGenericInterfaces();if (intfs.length != 0) {for (Type intf : intfs)out.format(" %s%n", intf.toString());out.format("%n");} else {out.format(" -- No Implemented Interfaces --%n%n");}out.format("Inheritance Path:%n");List<Class> l = new ArrayList<Class>();printAncestor(c, l);if (l.size() != 0) {for (Class<?> cl : l)out.format(" %s%n", cl.getCanonicalName());out.format("%n");} else {out.format(" -- No Super Classes --%n%n");}out.format("Annotations:%n");Annotation[] ann = c.getAnnotations();if (ann.length != 0) {for (Annotation a : ann)out.format(" %s%n", a.toString());out.format("%n");} else {out.format(" -- No Annotations --%n%n");}// production code should handle this exception more gracefully} catch (ClassNotFoundException x) {x.printStackTrace();}}private static void printAncestor(Class<?> c, List<Class> l) {Class<?> ancestor = c.getSuperclass();if (ancestor != null) {l.add(ancestor);printAncestor(ancestor, l);}} }</span>


?

給出一個運行實例. <span style="font-family:SimHei;font-size:14px;">$ java ClassDeclarationSpy java.util.concurrent.ConcurrentNavigableMap Class:java.util.concurrent.ConcurrentNavigableMapModifiers:public abstract interfaceType Parameters:K VImplemented Interfaces:java.util.concurrent.ConcurrentMap<K, V>java.util.NavigableMap<K, V>Inheritance Path:-- No Super Classes --Annotations:-- No Annotations -</span>
?

它被聲明在java.util.concurrent.ConcurrentNavigableMap?中,聲明如下:

<span style="font-family:SimHei;font-size:14px;">public interface ConcurrentNavigableMap<K,V>extends ConcurrentMap<K,V>, NavigableMap<K,V> <span style="BACKGROUND-COLOR: #ffffff"></span></span> ? 注意,因為它是一個接口,它隱式的是abstract.編譯器會自動的將這個修飾符添加進去. ? <span style="font-family:SimHei;font-size:14px;">$ java ClassDeclarationSpy "[Ljava.lang.String;" Class:java.lang.String[]Modifiers:public abstract finalType Parameters:-- No Type Parameters --Implemented Interfaces:interface java.lang.Cloneableinterface java.io.SerializableInheritance Path:java.lang.ObjectAnnotations:-- No Annotations --</span>
?

?? 由于數組是運行時的對象,因此它的所有信息被java虛擬機定義.特別的是,數組實現了?Cloneablejava.io.Serializable?

?? 和它的直接父類是Object.

?

<span style="font-family:SimHei;font-size:14px;">$ java ClassDeclarationSpy java.io.InterruptedIOException Class:java.io.InterruptedIOExceptionModifiers:publicType Parameters:-- No Type Parameters --Implemented Interfaces:-- No Implemented Interfaces --Inheritance Path:java.io.IOExceptionjava.lang.Exceptionjava.lang.Throwablejava.lang.ObjectAnnotations:-- No Annotations --</span>
? <span style="font-family:SimHei;font-size:14px;">$ java ClassDeclarationSpy java.security.Identity Class:java.security.IdentityModifiers:public abstractType Parameters:-- No Type Parameters --Implemented Interfaces:interface java.security.Principalinterface java.io.SerializableInheritance Path:java.lang.ObjectAnnotations:@java.lang.Deprecated()</span>
?

?

??? 3.訪問類成員

???? 在Class中有兩類方法可以用來訪問類的字段,方法,構造函數.第一類方法是查找本類中特定的方法,

???? 另一類是查找本類及其父類的方法.

???? 在面的表格是對這些方法的簡單總結.


Class Methods for Locating FieldsClass?APIList of members?Inherited members?Private members?
getDeclaredField()nonoyes
getField()noyesno
getDeclaredFields()yesnoyes
getFields()yesyesno


Class Methods for Locating MethodsClass?APIList of members?Inherited members?Private members?
getDeclaredMethod()nonoyes
getMethod()noyesno
getDeclaredMethods()yesnoyes
getMethods()yesyesno


Class Methods for Locating ConstructorsClass?APIList of members?Inherited members?Private members?
getDeclaredConstructor()noN/A1yes
getConstructor()noN/A1no
getDeclaredConstructors()yesN/A1yes
getConstructors()yesN/A1no

1?Constructors are not inherited..

??? 給出你感興趣的類的名稱和類成員的類型(CONSTRUCTOR, FIELD, METHOD, CLASS, ALL),ClassSpy 將會使用get*s()?

?? 方法去得到該類型公共成員的列表,包括繼承的成員,

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Member; import static java.lang.System.out;enum ClassMember { CONSTRUCTOR, FIELD, METHOD, CLASS, ALL }public class ClassSpy {public static void main(String... args) {try {Class<?> c = Class.forName(args[0]);out.format("Class:%n %s%n%n", c.getCanonicalName());Package p = c.getPackage();out.format("Package:%n %s%n%n",(p != null ? p.getName() : "-- No Package --"));for (int i = 1; i < args.length; i++) {switch (ClassMember.valueOf(args[i])) {case CONSTRUCTOR:printMembers(c.getConstructors(), "Constructor");break;case FIELD:printMembers(c.getFields(), "Fields");break;case METHOD:printMembers(c.getMethods(), "Methods");break;case CLASS:printClasses(c);break;case ALL:printMembers(c.getConstructors(), "Constuctors");printMembers(c.getFields(), "Fields");printMembers(c.getMethods(), "Methods");printClasses(c);break;default:assert false;}}// production code should handle these exceptions more gracefully} catch (ClassNotFoundException x) {x.printStackTrace();}}private static void printMembers(Member[] mbrs, String s) {out.format("%s:%n", s);for (Member mbr : mbrs) {if (mbr instanceof Field)out.format(" %s%n", ((Field)mbr).toGenericString());else if (mbr instanceof Constructor)out.format(" %s%n", ((Constructor)mbr).toGenericString());else if (mbr instanceof Method)out.format(" %s%n", ((Method)mbr).toGenericString());}if (mbrs.length == 0)out.format(" -- No %s --%n", s);out.format("%n");}private static void printClasses(Class<?> c) {out.format("Classes:%n");Class<?>[] clss = c.getClasses();for (Class<?> cls : clss)out.format(" %s%n", cls.getCanonicalName());if (clss.length == 0)out.format(" -- No member interfaces, classes, or enums --%n");out.format("%n");} }

?

?? 給出一個示例,以及相應輸出結果

<span style="font-family:SimHei;font-size:14px;">$ java ClassSpy java.lang.ClassCastException CONSTRUCTOR Class:java.lang.ClassCastExceptionPackage:java.langConstructor:public java.lang.ClassCastException()public java.lang.ClassCastException(java.lang.String</span>


?

給出一個示例,以及相應輸出結果 <span style="font-family:SimHei;font-size:14px;">$ java ClassSpy java.nio.channels.ReadableByteChannel METHOD Class:java.nio.channels.ReadableByteChannelPackage:java.nio.channelsMethods:public abstract int java.nio.channels.ReadableByteChannel.read(java.nio.ByteBuffer) throws java.io.IOExceptionpublic abstract void java.nio.channels.Channel.close() throwsjava.io.IOExceptionpublic abstract boolean java.nio.channels.Channel.isOpen()</span>
?

$ java ClassSpy ClassMember FIELD METHOD Class:ClassMemberPackage:-- No Package --Fields:public static final ClassMember ClassMember.CONSTRUCTORpublic static final ClassMember ClassMember.FIELDpublic static final ClassMember ClassMember.METHODpublic static final ClassMember ClassMember.CLASSpublic static final ClassMember ClassMember.ALLMethods:public static ClassMember ClassMember.valueOf(java.lang.String)public static ClassMember[] ClassMember.values()public final int java.lang.Enum.hashCode()public final int java.lang.Enum.compareTo(E)public int java.lang.Enum.compareTo(java.lang.Object)public final java.lang.String java.lang.Enum.name()public final boolean java.lang.Enum.equals(java.lang.Object)public java.lang.String java.lang.Enum.toString()public static <T> T java.lang.Enum.valueOf(java.lang.Class<T>,java.lang.String)public final java.lang.Class<E> java.lang.Enum.getDeclaringClass()public final int java.lang.Enum.ordinal()public final native java.lang.Class<?> java.lang.Object.getClass()public final native void java.lang.Object.wait(long) throwsjava.lang.InterruptedExceptionpublic final void java.lang.Object.wait(long,int) throwsjava.lang.InterruptedExceptionpublic final void java.lang.Object.wait() hrows java.lang.InterruptedExceptionpublic final native void java.lang.Object.notify()public final native void java.lang.Object.notifyAll()


?

?? 接口?java.nio.channels.ReadableByteChannel?定義了?read(). 其余的方法都是繼承自父類.
???

?? 對于字段結果的字段部分,枚舉常量被列了出來.

?? 對于字段結果的方法部分,發現方法的名稱包括定義這個方法的類的名稱. toString() 方法是被Enum是實現的,而不是

?? 繼承Object的.如果使用Field.getDeclaringClass(),段代碼可以被修改的更加明顯.下面的代碼段展示了一個可行的解決辦法:

<span style="font-family:SimHei;font-size:14px;">if (mbr instanceof Field) {Field f = (Field)mbr;out.format(" %s%n", f.toGenericString());out.format(" -- declared in: %s%n", f.getDeclaringClass()); } </span>
?

總結

以上是生活随笔為你收集整理的Java反射基础(一)--Class对象获取的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。