第十四章 类型信息
第十五章 泛型
Class对象
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {
private static final int ANNOTATION= 0x00002000;
private static final int ENUM = 0x00004000;
private static final int SYNTHETIC = 0x00001000;
private static native void registerNatives();
static {
registerNatives();
}
/*
* Private constructor. Only the Java Virtual Machine creates Class objects.
* This constructor is not used and prevents the default constructor being
* generated.
*/
private Class(ClassLoader loader) {
// Initialize final field for classLoader. The initialization value of non-null
// prevents future JIT optimizations from assuming this final field is null.
classLoader = loader;
}
......
}
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean,byte,char,short,int,long},float,and double), and the keyword void are also represented as Class objects.Class has no public constructor. Instead Class objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the defineClass method in the class loader.
Class对象由JVM创建,表征运行时类(枚举、数组)和接口(注解)、基本数据类型、void的元信息。
每个类都有一个Class对象,每当编写并且编译一个新类就会产生一个对应Class对象(保存在同名.class文件里),即在内存中每个类有且只有一个相对应的Class对象,它被用来创建这个类的所有对象。
所有的类都是在对其第一次使用时动态加载到JVM中的,当程序第一次调用类的静态成员时,就会加载这个被使用的类,使用new操作符创建类的新实例对象也会被当作调用类的静态成员,类加载器首先会检查这个类的Class对象是否已被加载,如果还没有加载,默认的类加载器就会先根据类名查找.class文件加载到内存中,此时相当于Class对象也就被载入内存了,同时Class对象可以被用来创建这个类的所有实例对象。
获取Class对象引用的方式:
- 通过getClass()方法
- Class类的静态方法forName("the fully qualified name of the desired class")
- 字面常量的方式.class
反射
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。在java.lang.reflect类库中,我们常用的类主要有Constructor类表示类的构造方法,利用它可以在运行时动态创建对象、Field表示表示的类的成员变量,通过它可以在运行时动态修改成员变量的属性值、Method表示类的成员方法,通过它可以动态调用对象的方法。
public class Test{
public String field ;
public Test(String field) {
this.field= field;
}
public void setField(String field) {
this.field= field;
}
public static void main(String[] args) throws Exception{
Class clazz = Test.class;
Constructor cons = clazz.getConstructor(String.class);
Test test = (Test)cons.newInstance("field");
System.out.println(test.field);
Field field = clazz.getDeclaredField("field");
field.set(test,"new field");
System.out.println(test.field);
Method method = clazz.getDeclaredMethod("setField", String.class);
method.invoke(test,"new new field");
System.out.println(test.field);
}
}
//## output ##
//field
//new field
//new new field
泛型
JDK 5中引入的一个新特性,提供编译期的类型检查,编译后的class文件中不包含任何泛型信息(类型擦除),泛型约束是为了提供编译期类型的检查避免将错误延续到运行时期 。
public class Test<T> {
public T field;
public Test(T field) {
this.field = field;
}
}
泛型类 泛型接口 泛型方法
// 泛型类
public class Generic<T> {
private T field;
public T getField() {
return field;
}
}
// 泛型接口
public interface Generator<T> {
public T next();
}
public class Test{
// 泛型方法
public <T> void method(T t) { }
}
类型通配符
无限定通配符 <?>
上界通配符 <? extends T>
下界通配符 <? super T>