实例070 实例化Class类的几种方式 实例说明 Java
的数据类型可以分成两类,即引用类型和原始类型。无论哪种类型的对象,Java
虚拟机都会实例化不可变的java.lang.Class
对象。它提供了在运行时检查对象属性的方法,这些属性包括它的成员和类型信息。更重要的是Class
对象是所有反射APl
的入口。本实例将演示如何获得Class
对象。实例的运行效果如图7.15所示。 多学两招:Class
类是泛型类,可以使用@SuppressWarnings("unchecked")
忽略泛型或者使用Class<?>
类型。
实现过程 (2)编写类ClassTest
,在该类的main()
方法中,演示各种获得Class
对象的方法。关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package com.mingrisoft;import java.util.Date;public class ClassTest { @SuppressWarnings("unchecked") public static void main (String[] args) throws ClassNotFoundException { System.out.println("第1种方法:Object.getClass()" ); Class c1 = new Date ().getClass(); System.out.println(c1.getName()); System.out.println("第2种方法:类名.class语法" ); Class c2 = boolean .class; System.out.println(c2.getName()); System.out.println("第3种方法:Class.forName()" ); Class c3 = Class.forName("java.lang.String" ); System.out.println(c3.getName()); System.out.println("第4种方法:包装类.TYPE" ); Class c4 = Double.TYPE; System.out.println(c4.getName()); } }
运行效果:
1 2 3 4 5 6 7 8 第1种方法:Object.getClass() java.util.Date 第2种方法:类名.class语法 boolean 第3种方法:Class.forName() java.lang.String 第4种方法:包装类.TYPE double
技术要点 通常有以下4种方式可以获得Class
对象。
Object.getClass()
:如果一个类的对象可用,则最简单的获得Class
的方法是使用Object.getClass()
。当然,这种方式只对引用类型有用。
.class
语法:如果类型可用,但没有对象则可以在类型后加上“.class
”来获得Class
对象。这也是使原始类型(基本数据类型)获得Class
对象的最简单的方式。
Class.forName("类全名")
:如果知道类的全名,则可以使用静态方法Class.forName("类全名")
来获得Class
对象。该方法不能用在原始类型(基本数据类型)上,但是可以用在原始类型数组上。
包装类的TYPE
域:每个原始类型和void
都有包装类,利用其TYPE
域就可以获得Class
对象。
实例071 查看类的声明 实例说明 通常类的声明包括常见修饰符(public
、protected
、private
、abstract
、static
、final
和strictfp
等)、类的名称、类的泛型参数、类的继承类(实现的接口)和类的注解等。本实例将演示如何用反射获得这些信息。实例的运行效果如图7.16所示。
实现过程 编写类ClassDeclarationViewer
,在main()
方法中输出了与类声明相关的各个项。关键代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 package com.mingrisoft;import java.lang.annotation.Annotation;import java.lang.reflect.Modifier;import java.lang.reflect.Type;import java.lang.reflect.TypeVariable;public class ClassDeclarationViewer { public static void main (String[] args) throws ClassNotFoundException { Class<?> clazz = Class.forName("java.util.ArrayList" ); System.out.println("类的标准名称:" + clazz.getCanonicalName()); System.out.println("类的修饰符:" + Modifier.toString(clazz.getModifiers())); TypeVariable<?>[] typeVariables = clazz.getTypeParameters(); System.out.print("类的泛型参数:" ); if (typeVariables.length != 0 ) { for (TypeVariable<?> typeVariable : typeVariables) { System.out.println(typeVariable + "\t" ); } } else { System.out.println("空" ); } Type[] interfaces = clazz.getGenericInterfaces(); System.out.println("类所实现的接口:" ); if (interfaces.length != 0 ) { for (Type type : interfaces) { System.out.println("\t" + type); } } else { System.out.println("\t" + "空" ); } Type superClass = clazz.getGenericSuperclass(); System.out.print("类的直接继承类:" ); if (superClass != null ) { System.out.println(superClass); } else { System.out.println("空" ); } Annotation[] annotations = clazz.getAnnotations(); System.out.print("类的注解:" ); if (annotations.length != 0 ) { for (Annotation annotation : annotations) { System.out.println("\t" + annotation); } } else { System.out.println("空" ); } } }
多学两招:通常只能通过API
来查看类的定义,不过Java
反射还提供了另一种方式来获得类的信息,读者也可以在程序中使用这些信息。另外,使用getInterfaces()
方法也可以获得对象类的所有接口,但是不包含泛型信息。即使是getSuperclass()
方法也不能获得有泛型信息的父类。
技术要点 Class
类的实例表示正在运行的Java
应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为Class
对象的一个类,所有具有相同元素类型和维数的数组都共享该Class
对象。基本的Java
类型(boolean
、byte
、char
、short
、int
、long
、foat
和double
)和关键字void
也表示为Class
对象。它没有公共构造方法。Class
对象是在加载类时由Java
虚拟机以及通过调用类加载器中的defineClass
方法自动构造的。本实例使用的方法如表71所示。
方法
描述
static Class<?> forName(String className)
Returns the Class object associated with the class or interface with the given string name.
TypeVariable<Class<T>>[] getTypeParameters()
Returns an array of TypeVariable objects that represent the type variables declared by the generic declaration represented by this GenericDeclaration object, in declaration order.
Type[] getGenericInterfaces()
Returns the s representing the interfaces directly implemented by the class or interface represented by this object.Type