java 类型信息
来源:互联网 发布:centos搭建smtp服务器 编辑:程序博客网 时间:2024/05/21 15:05
运行时类型信息使得你在程序运行时发现和使用类型信息
我们如何使用类型信息呢?主要有两种方式:一是传统的RTTI,它假设在编译时我们知道所有的类型;二是反射机制,它允许我们在运行时发现和使用类的信息。
为什么使用RTTI(Run-Time Type Identification)
实际上他是把所有的对象当Object持有–会自动将结果转型为Shape。这是RTTI的最基本的使用形式,因为在java中,所有的类型都是在运行时检查的。这也是RTTI名字的含义,在运行时,识别一个对象的类型。
class对象
类是程序的一部分,每个类都有一个Class对象。所有的类都是在第一次使用时,动态加载到JVM中的。
package type;/** * Created by leon on 2017/2/25. */public class SweetShop { public static void main(String[] args) { System.out.println("Inside main..."); new Candy(); System.out.println("After createing Candy"); try { Class.forName("type.Gum"); } catch (ClassNotFoundException e) { System.out.println("Couldn't find Gum"); } System.out.println("After Class.forName(\"Gum\")"); new Cookie(); System.out.println("After creating Cookie"); }}class Candy{ static { System.out.println("Loading Candy"); }}class Gum{ static { System.out.println("loading Gum"); }}class Cookie{ static{ System.out.println("Loading Cookie"); }}
Inside main...Loading CandyAfter createing Candyloading GumAfter Class.forName("Gum")Loading CookieAfter creating Cookie
所有的类的使用都是在第一次使用时,动态加载到JVM中的。当程序创建的第一个对类的静态成员的引用时,就会加载这个类。这个证明构造器也是累的静态方法,即使在构造器前没有使用static关键字。因此,用new操作符创建的新对象也会被当做对类的静态成员的引用。
java程序在它开始运行之前并非完全加载,其各个部分是在必需时才加载的。动态加载能力使能的行为,在诸如C++这样的静态加载的语言中很难或者根本不可能复制的。
类加载器首先会验证Class对象是否完整加载,一旦某各类的Class对象呗载入内存,它会被利用创建这个类的所有对象。
上面每一个类都有一个static字句,该字句在类的第一次加载时执行。
Class.forName(“…”) 是取得Class对象的引用的另一种便捷的方法,因为你不用为了获得Class引用而持有该类型的对象。但但是如果你已经拥有了一个感兴趣的对象,那就调用getClass()方法来获取Class引用了,这个方法属于Object对象的一部分,将返回给对象实际类型Class的引用。Class还包括很多其他有用的方法:
package type;/** * Created by leon on 2017/2/25. */interface HashBatteries{}interface Waterproof{}interface Shoots{}class Toy{ Toy() {} Toy(int i){}}class FancyToy extends Toy{ FancyToy() { super(1); }}public class ToyTesy { static void printInfo(Class cc){ System.out.println("Class name:"+cc.getName() +" -- is Interface? :"+cc.isInterface()); System.out.println("Simple name:"+cc.getSimpleName()); System.out.println("Canonical name:"+cc.getCanonicalName()); } public static void main(String[] args) { Class c = null; try { c = Class.forName("type.FancyToy"); } catch (ClassNotFoundException e) { System.out.println("Can't find FancyToy"); e.printStackTrace(); } printInfo(c); for (Class aClass : c.getInterfaces()) { printInfo(aClass); } Object obj = null; Class up = c.getSuperclass(); try { obj = up.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } printInfo(obj.getClass()); }}
Class name:type.FancyToy -- is Interface? :falseSimple name:FancyToyCanonical name:type.FancyToyClass name:type.Toy -- is Interface? :falseSimple name:ToyCanonical name:type.Toy
类字面常量
Java提供另一种方法来生成对Class对象的引用,即类字面常量,对上述程序来说就是Fancy.class 。这样做不仅简单而且更安全,因为在编译时就会受到检查(因此不需要try catch),并且它根除了对forName() 方法的调用,所以更高效。类字面常量不仅可以应用于普通的类,也可以应用于接口、数组、以及基本数据类型。
值得注意的是,使用“.class”来创建对Class对象的引用是,不会自动的初始化该Class对象。准备工作包含三个不走
- 加载。 类加载器执行,查找字节码,并从这些字节码中创建一个Class对象。
- 链接。 在连接阶段将验证类中的字节码,为静态域分配空间,并且如果必须的话,将解析这个类创建的对其他类的引用。
- 初始化。如果该类具有超类,则对其进行初始化,执行静态初始化器和静态初始化代码块。
初始化被延迟到了对静态方法(构造器隐式地是静态的)或者非静态域进行首次引用是才执行:
package thingkingInJava.type;import java.util.Random;/** * Created by leon on 2017/3/5. */class Initable{ static final int staticFinal = 47; static final int staticFinal2 =ClassInitialization.rand.nextInt(1000); static { System.out.println("Initializing Initable"); }}class Initable2{ 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) { Class initable = Initable.class; System.out.println("After creating Initable ref"); //Does not trigger initalization System.out.println(Initable.staticFinal); //Does trigger initalization System.out.println(Initable.staticFinal2); //Does trigger initalization System.out.println(Initable2.staticNonFinal); try { Class initable3 = Class.forName("thingkingInJava.type.Initable3"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println("After creating Initable3 ref"); System.out.println(Initable3.staticNonFinal); }}
After creating Initable ref47Initializing Initable258Initializing Initable2147Initializing Initable3After creating Initable3 ref74
初始化实现了尽可能的“惰性”。从对initable引用的创建可以看出,仅使用.class语法获取的对类的引用不会引发初始化。但是为了产生Class引用,Class.forName()会立即就进行初始化,就像对initable3引用的创建中看到的。
- java类型信息
- Java 类型信息
- java基础-类型信息
- Java中的类型信息
- Java类型信息:RTTI
- java 类型信息
- java 类型信息 笔记
- Java类型信息
- Java 类型信息知识点
- Thinking in Java :类型信息
- java反射---获取类型信息
- java基础之类型信息
- thingking in Java 类型信息
- Thinking in Java -- 类型信息
- 理解Java的类型信息
- java学习笔记-----类型信息
- Java泛型中类型信息的擦除
- 《Java 编程思想》--第十四章:类型信息
- 1066. 图像过滤(15)
- poj 3710 Christmas Game(博弈 无向图删边游戏)
- IIC
- 数据库优化---空间换时间优化
- C primer plus 第八章 字符输入输出与输入验证 编程练习 个人答案
- java 类型信息
- Android开发——Bitmap(位图)全方位解析(一)
- jdk1.8 LongAdder源码学习
- 直播技术总结(四)音视频数据压缩及编解码基础
- 1070. 结绳(25)
- 硬盘基础知识
- 【Spring】使用Spring发送邮件
- 图片加载框架,Glide
- 【Unity优化】Unity中究竟能不能使用foreach?