java中的反射 2.1——类:获取类对象@译自Oracle官方文档

6 篇文章 0 订阅
5 篇文章 0 订阅

译自:http://docs.oracle.com/javase/tutorial/reflect/class/classNew.html

java.lang.Class类是所有反射操作的切入点。除java.lang.reflect.ReflectPermission类外,所有的java.lang.reflect包中的类都没有公共构造函数。要使用这些类就需要借助Class类中的特定方法。有许多种方法获取一个Class,这些方法的不同之处在于当前可以访问到的是一个对象(object)、是一个类(class)的名字还是一个已经存在的类。

Object.getClass()

如果已经有一个对象的实例,那么获取它的Class最简单的方法就是调用Object.getClass()。这个方法当然只适用于继承自Object的引用类型。例子:


Class c = "foo".getClass();

返回String的Class。


Class c = System.console().getClass();

静态方法System.console返回虚拟机中唯一的控制台(console),而getClass()返回的是java.io.Console对应的Class。


enum E { A, B }
Class c = A.getClass();

A是枚举类型E的一个实例;因此getClass()返回的是枚举类型E对应的Class。


byte[] bytes = new byte[1024];
Class c = bytes.getClass();

由于数组也是对象,所以也可以对一个数组的实例调用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()返回的是java.util.HashSet对应的Class。


.class语法

如果一种类型是可用的但我们并没有它的实例。那么可以在类型后边加后缀“.class”来获取Class。这也是获取一个基本类型(比如int,char)的Class最简单的方法

boolean b;
Class c = b.getClass();   // 编译错误

Class c = boolean.class;  // 正确的写法

注意boolean.getClass() 语句会造成编译错误因为boolean是一个基本类型因此不能被间接引用(dereferenced)。应该使用.class语法来返回boolean对应的Class。


Class c = java.io.PrintStream.class;

变量c被声明为一个java.io.PrintStream对应的Class。


Class c = int[][][].class;

.class语法也可用于获取一个多维数组的Class。


Class.forName()

如果可以得到一个类的完全限定名称(fully-qualified name),那么就可以使用静态方法Class.forName()来获取对应的Class。这种方法不能用于基本类型。要获得一个数组类型的完全限定名称可以使用Class.getName()。


Class c = Class.forName("com.duke.MyLocaleServiceProvider");

这过语句会从给出的完全限定名称创建一个类。


Class cDoubleArray = Class.forName("[D");

Class cStringArray = Class.forName("[[Ljava.lang.String;");

变量cDoubleArray 被声明为一个double类型数组所对应的Class(与double[].class结果相同)。变量cStringArray 被声明为一个String类型的二维数组所对应的Class(与String[][].class结果相同)。


基本类型的包装类的TYPE字段

.class语法使用起来更方便并更适合于获取基本类型的Class;但是依然有别的方法获取。每一种基本类型以及void类型都有一个包装类用以将基本类型封装成引用类型。每一个包装类都有一个TYPE字段,字段值便是被包装的基本类型的Class。

Class c = Double.TYPE;

Double.TYPE与double.class是相同的。

Class c = Void.TYPE;

Void.TYPE与void.class是相同的。

返回Class的方法

有一些反射API可以返回Class,但这些方法只能用在Class已经被直接或间接的获取到时。


Class.getSuperclass()
返回给定类的父类。
Class c = javax.swing.JButton.class.getSuperclass();
javax.swing.JButton的父类是lavax.swing.AbstractButton。

Class.getClasses()
返回该类及其所有子类的所有的公共类、接口和枚举类型
Class<?>[] c = Character.class.getClasses();
Character有两个成员类Character.Subset和Character.UnicodeBlock。

Class.getDeclaredClasses()
返回该类所有声明的接口和枚举类型
Class<?>[] c = Character.class.getDeclaredClasses();
Character有两个公共成员类 Character.Subset和Character.UnicodeBlock以及一个私有类 Character.CharacterCache。

Class.getDeclaringClass()

java.lang.reflect.Field.getDeclaringClass()

java.lang.reflect.Method.getDeclaringClass()

java.lang.reflect.Constructor.getDeclaringClass()
返回有这些成员声明的Class。匿名类将不会有声明类,但会有封闭类。
import java.lang.reflect.Field;

Field f = System.class.getField("out");
Class c = f.getDeclaringClass();
字段out在类System中声明。
 
public class MyClass {
    static Object o = new Object() {
        public void m() {} 
    };
    static Class<c> = o.getClass().getEnclosingClass();
}
由o定义的匿名类的声明类是null。


Class.getEnclosingClass()
返回该类的立即封闭类(  immediately enclosing class
Class c = Thread.State.class().getEnclosingClass();
枚举类型Thread.State的封闭类是Thread。
 
public class MyClass {
    static Object o = new Object() { 
        public void m() {} 
    };
    static Class<c> = o.getClass().getEnclosingClass();
}
由o定义的匿名类被MyClass封闭。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值