您的位置:首页 > 编程语言 > Java开发

Java编程思想 ch14 类型信息

2018-03-17 19:45 806 查看

key–运行时如何识别类型信息

RTTI Runtiem Type Information


14.2 Class 对象

类是程序的一部分,每个类都有一个Class对象。每当编写并编译了一个类,都会产生一个Class对象(保存在一个同名的.class文件)。为了产生这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为“类加载器”的子系统。

动态加载,当程序创建第一个对类的静态成员的引用时,就会将这个类加载到JVM中。–>证明构造器是静态方法。Java程序在它开始运行之前并非被完全加载,各个部分是在必需时才加载。对比静态加载

类加载器先检查这个Class对象是否已经加载,如果没有加载,默认的类名加载器根据类名查找.class文件。这个类的字节码被加载时,它们会接受验证,以确保其没有被破坏,并且不包含不良代码。

一旦一个类的Class对象被载入内存,就被用于创建这个类的所有对象。

class.forName();

包名加类名

class.getClass();

getName() 全限定类名

getSimpleNmae() 和 getCanonicalName()

isInterface()

getInterfaces()

newInstance() 得到Object引用指向调用方法的类型的对象,必须带有默认构造器。返回Object对象

14.2.1

类名.class 等同调用forName(),基本类型的包装类还有TYPE字段。

等价于header 2
boolean.classBoolean.TYPE
char.classCharacter.TYPE
byte.classByte.TYPE
short.classShort.TYPE
int.classInteger.TYPE
long.classLong.TYPE
float.classFloat.TYPE
double.classDouble.TYPE
void.classVOid.TYPE
当使用“.class”来创建对Class对象的引用,不会自动初始化该Class对象。使用类的准备工作:

1.加载。类加载器执行,在classpath指定的路径中去查找字节码?并非必须?,从这些字节码中创建一个Class对象。

2.链接。验证类中字节码,为静态域分配存储空间。

3.初始化。有超类,超类初始化。执行静态初始化和静态初始化块。(初始化被延迟到对静态方法或者非常数静态域首次调用时才执行。)

分析:也就是说1,2步骤是执行了的。

package Ch14;
import java.util.*;
class Initable{
//如果一个static final是“编译期常量”,如下 staticFinal,不需要对类初始化就可以读取。
static final int staticFinal = 47;
// staticFinal虽然是static Final但不是“常量”,会触发初始化。
static final int staticFinal2 =ClassInitialization.rand.nextInt(1000);
static{
System.out.println("Initializing initable");
}
}
class Initable2{
//如果一个static域不是final,对它的访问总是要先链接(为这个域分配存储空间)和初始化(初始化该存储空间)
static int staticNonFinal = 147;
static{
System.out.println("Initializing Initable2");
}
}
class Initable3{
static int staticNonFinal = 74;
static{
System.out.println("Initializing Initable3");
}
}
public class ClassInitialization {
public static Random rand = new Random(47);

public static void main(String[] args) throws Exception{

Class initable = Initable.class;
//Does not trigger initialization
System.out.println("After creating Initable ref");
//trigger initialization
System.out.println(Initable.staticFinal);

System.out.println(Initable.staticFinal2);

System.out.println(Initable2.staticNonFinal);

Class initable3 = Class.forName("Ch14.Initable3");

System.out.println("After creating Initable3 ref");

System.out.println(Initable3.staticNonFinal);
}
}
After creating Initable ref
47
Initializing initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3 ref
74


14.2.2 泛化的Class引用

package Ch14;

public class BoundedClassReference {
public static void main(String[] args) {
Class<? extends Number> bounded = int.class;
// ? 代表任何事物,extends加以限制。
bounded = double.class;
bounded = Number.class;
Class intClass = int.class;
Class<Integer> genericIntClass = int.class;
genericIntClass = Integer.class;
intClass = double.class;
// gengricIntClass = double.class;//Illegal
}
}
//将泛型用于Class对象后,newInstance()将返回确切的类型。而不只是Object

public class GenericToyTest{
public static void main(String[] args) throws Exception
{
Class<FancyToy> fiClass = FancyToy.class;
FancyToy fancyToy =fiClass.newInstance();
Class<? super FancyToy> up = fiClass.getSuperclass();
Object obj = up.newInstance();

}
}


14.2.3 新的转型语法

class Building {}
class House extends Building{}
public class ClassCasts{
public static void main(String[] args){
Building b = new House();
Class<House> houseType = House.class;
House h = houseType.cast(b);
// 接受参数并将其转换为Class引用类型。
h = (House)b;
}
}


14.2 类型转换前先做检查

知道子类的对象肯定也是基类的对象,所以向上转型不需要显示操作。

instanceof

if(x instanceof Dog)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Java编程思想