JAVA类型信息——Class对象(转载)
JAVA类型信息——Class对象
一、RTTI概要
1、类型信息RTTI :即对象和类的信息,例如类的名字、继承的基类、实现的接口等。
2、类型信息的作用:程序员可以在程序运行时发现和使用类型信息。
3、RTTI真正含义:运行时,识别一个对象的类型。
4、如何在程序运行时识别对象和类的信息?
1)传统RTTI:即在编译时已知道了所有的类型。
2)反射机制:在程序运行时发现和使用类的信息。
5、RTTI的使用
import java.util.*; //List支持泛型
//import java.awt.List; 不支持泛型
import java.util.Arrays;
abstract class Shapes{
void draw() {System.out.println(this + ".draw()");}
abstract public String toString();
}
class Circle extends Shapes{
public String toString() {return "Circle";}
}
class Triangle extends Shapes{
public String toString() {return "Triangle";}
}
class Square extends Shapes{
public String toString() {return "Square";}
}
class Test{
public static List<Shapes> getList(){
List<Shapes> list_aShapes = Arrays.asList(new Circle() , new Square(), new Triangle());
return list_aShapes;
}
}
public class Shape {
public static void main(String[] args) {
List<Shapes> list_aShapes = Test.getList();
for(Shapes ob_aShapes : list_aShapes) {
ob_aShapes.draw();
}
}
}
运行结果:Circle.draw()
Square.draw()
Triangle.draw()
结果分析:(1)toString()都继承Object类的toSting(),派生类的toString()都会覆盖基类的该方法。
(2)Shapes.draw()中的this间接调用toString()。
(3)假设Test类是服务器端提供给客户端使用的一个类,客户端调用该类的方法(这里main()调用)获得一个泛化引用,显然,客户端并不知道泛化引用中的确切类型,而程序员需要使用到某一个确切类型对象,这时,我们就需要到RTTI。在上面的例子中,我们只是打印出泛化引用的所有类型。
二、Class对象
Class对象概述 |
(1)持有RTTI信息 (2)每个类都有一个Class对象,每当编译一个新类就产生一个Class对象。 (3) Class引用总是指向某个Class对象。Class引用表示的就是它所指向的对象的确切类型,而该对象便是Class类的一个对象。 () |
||
forName() |
(1) 获取Class对象的一个引用,但引用的类还没有加载(该类的第一个对象没有生成)就加载了这个类. (2) 为了产生Class引用,forName()立即就进行了初始化。 |
||
Object-getClass() |
获取Class对象的一个引用,返回表示该对象的实际类型的Class引用。 |
||
getName() |
获取全限定的类名(包括包名),即类的完整名字。 |
||
getSimpleName() |
获取类名(不包括包名) |
||
getCanonicalName() |
获取全限定的类名(包括包名) |
||
isInterface() |
判断Class对象是否是表示一个接口 |
||
getInterface() |
返回Class对象,表示Class对象所引用的类所实现的所有接口。 |
||
getSupercalss() |
返回Class对象,表示Class对象所引用的类所继承的直接基类。应用该方法可在运行时发现一个对象完整的继承结构。 |
||
newInstance() |
返回一个Oject对象,是实现“虚拟构造器”的一种途径。 “虚拟构造器”:我不知道你的确切的类型,但无论如何都要正确创建你自己。 使用该方法创建的类,必须带有默认的构造器。 |
||
cast() |
接受一个对象为参数,并将其转型为Class引用的类型。该法一般是在无法使用普通转型的情况下使用。 |
||
getClassLoader() |
返回该类的类加载器。 |
||
getComponentType() |
返回表示数组组件类型的Class。 |
||
isArray() |
判定此 Class 对象是否表示一个数组类。 |
||
类字面常量 |
(1)一种用来生成对Class对象引用的方法。 (2)相对forName()而言,效率更高,而且不会立即引发初始化。 (3)方法:className.class;。 (4)既可用于普通类,也可用于接口、数组、基本数据类型。 |
||
…………等价于………… |
|||
boolean.class |
Boolean.class |
||
char.class |
Char.class |
||
byte.class |
Byte.class |
||
short.class |
Short.class |
||
int.class |
Integer.class |
||
long.class |
Long.class |
||
float.class |
Float.class |
||
double.class |
Double.class |
||
void.class |
Void.class |
||
泛化的Class引用 |
(1)实现方法:使用通配符“?”。 (2)Class<?>优于Class,即便他们是等价的。 (3)Class<?>的好处是明确地告诉编译器你选择了非具体的类版本,而不是由于碰巧或者疏忽而使用了一个非具体的类引用。 (4)创建一个范围:创建一个Class引用 ,使它被限定为某种类型<className>;或该类型的任何子类型,< ? extends superClass>;或者该类型的超类,< ? super super sunClassName> |
||
import java.lang.Class;
import java.lang.reflect.Constructor;
interface Iterface1{}
interface Iterface2{}
abstract class SuperClass{
SuperClass(){};
SuperClass(int i){}
static {System.out.println("creating SuperClass");}
}
class SunClass extends SuperClass implements Iterface1, Iterface2{
SunClass(){super(1);}
static {System.out.println("creating SunClass");}
}
class SunClass1 extends SuperClass implements Iterface1, Iterface2{
SunClass1(){super(1);}
static {System.out.println("creating SunClass1");}
}
public class ClassObject {
static void printInfo(Class cc) {
System.out.println("Class name:" + cc.getName()
+ " is Interface : " + cc.isInterface()
+" Simple name : " + cc.getSimpleName()
+ " Canonical name : " + cc.getCanonicalName());
}
public static void main(String[] args) {
System.out.println("/////forName()与类字面常量////////");
Class ob_aClass = null;
//对类的引用不引发初始化
Class ob_cClass = SuperClass.class;
System.out.println("After creating SuperClass");
try {
//立即初始化类
ob_aClass = Class.forName("rtti.SunClass");
System.out.println("After creating SunClass");
System.out.println("///////////////////////////////////");
}catch(ClassNotFoundException e){
System.out.println("Can't find SunClass.");
System.exit(1);
}
printInfo(ob_aClass);
System.out.println("///////Class引用实现的接口///////");
for(Class face : ob_aClass.getInterfaces())
printInfo(face);
System.out.println("//////Class引用的基类////////");
Class ob_bClass = ob_aClass.getSuperclass();
printInfo(ob_bClass);
System.out.println("///////newInstance()///////");
Object ob_aObject = null;
try {
ob_aObject = ob_aClass.newInstance();
//运行剖出异常 newInstance()该法必须由Class.forName()调用
//ob_aObject = ob_bClass.newInstance();
}catch(InstantiationException e){
System.out.println("Can't instante.");
System.exit(1);
}catch(IllegalAccessException e){
System.out.println("Can't access.");
System.exit(1);
}
printInfo(ob_aObject.getClass());
System.out.println("//////Class引用的泛型////////");
Class <? extends SuperClass> ob_dClass = SunClass.class;
printInfo(ob_dClass);
Class <? extends SuperClass> ob_eClass = SunClass1.class;
printInfo(ob_eClass);
//没有类型转换(Class<? super SunClass>),会出错,上位知道原因?
Class<? super SunClass> ob_fClass = (Class<? super SunClass>)
ob_dClass.getSuperclass();
printInfo( ob_fClass);
}
}
运行结果:
creating SuperClass
creating SunClass
After creating SunClass
///////////////////////////////////
Class name:rtti.SunClass is Interface : false Simple name : SunClass Canonical name : rtti.SunClass
///////Class引用实现的接口///////
Class name:rtti.Iterface1 is Interface : true Simple name : Iterface1 Canonical name : rtti.Iterface1
Class name:rtti.Iterface2 is Interface : true Simple name : Iterface2 Canonical name : rtti.Iterface2
//////Class引用的基类////////
Class name:rtti.SuperClass is Interface : false Simple name : SuperClass Canonical name : rtti.SuperClass
///////newInstance()///////
Class name:rtti.SunClass is Interface : false Simple name : SunClass Canonical name : rtti.SunClass
//////Class引用的泛型////////
Class name:rtti.SunClass is Interface : false Simple name : SunClass Canonical name : rtti.SunClass
Class name:rtti.SunClass1 is Interface : false Simple name : SunClass1 Canonical name : rtti.SunClass1
Class name:rtti.SuperClass is Interface : false Simple name : SuperClass Canonical name : rtti.SuperClass
JAVA类型信息——Class对象(转载)的更多相关文章
- Java基础 -- 深入理解Java类型信息(Class对象)与反射机制
一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RT ...
- JAVA类型信息——Class对象
JAVA类型信息——Class对象 一.RTTI概要 1.类型信息RTTI :即对象和类的信息,例如类的名字.继承的基类.实现的接口等. 2.类型信息的作用:程序员可以在程序运行时发现和使用类型信息. ...
- JAVA类型信息——反射机制
JAVA类型信息——反射机制 一.反射机制概述 1.反射机制:就是java语言在运行时拥有的一项自我观察的能力,java通过这种能力彻底了解程序自身的情况,并为下一步的动作做准备. 2.反射机制的功能 ...
- Java类型信息
一.引言 最近在阅读<Java编程思想>,学习一下java类型信息,现在做一下总结.Java如何让我们在运行时识别对象和类的信息的.主要有两种方式:一种是传统的“RTTI”,它假定我们在编 ...
- Thinking in Java -- 类型信息RTTI
Thinking in Java – 类型信息 个人感觉 java 中的比較难的部分了,在看了些netty源代码发现事实上这块很实用. 这章重点是RTTI和反射.先说下自己的理解 RTTI是执行时识别 ...
- Java类型信息(RTTI和反射)
要想在IT领域站得住脚,必须得不断地学习来强化自己,但是学过的技术不实践很容易便被遗忘,所以一直都打算开个博客,来记录自己学的知识,另外也可以分享给有需要的人! 最近在学习反射,为了更好地理解反射,就 ...
- 【Java核心技术】类型信息(Class对象 反射 动态代理)
1 Class对象 理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息.Class对象就是用来创建所有“常规”对象的,J ...
- Java 类型信息 —— 获取泛型类型的类对象(.class)
How to get a class instance of generics type T 考虑泛型类Foo<T>,在其成员中,如果想获取类型(type)T的类实例(class inst ...
- Java 类型信息
<Thinking in Java 4th>第14章 类型信息 运行时类型信息(Run-Time Type Identification)使得你可以在程序运行时发现和使用类型信息. 14. ...
随机推荐
- FAT12中,如何定位大于一个扇区(512B)的文件内容
[0]README 0.1)本文旨在于 演示在FAT12中, 如何取定位大于 512B 的文件内容,和查看它: 0.2)如何制作FAT12文件系统,以及如何向文件中添加temp.txt文件,参见: { ...
- EasyNVR H5无插件摄像机直播解决方案前端解析之:videojs的使用
video.js的基本使用方法 一.videojs的初始化加载 videojs初始化加载分为两中 1.标签式加载 在引入videojs加载文件的前提下,可以在video标签中添加属性值"da ...
- 九度OJ 1017:还是畅通工程 (最小生成树)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4789 解决:2382 题目描述: 某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离.省政府"畅通工程&quo ...
- 我的Java开发学习之旅------>工具类:Java使用正则表达式分离出字符串中的中文和英文
今天看到一个工具类使用正则表达式将一大段字符串中的中文和英文都分离出来了,在此记录一下,读者可以收藏! import java.util.ArrayList; import java.util.Col ...
- Nginx + Tomcat 应用证书启用 SSL
第一部分 简述 - 附:相关概念 1 Nginx 是什么? - 2 Tomcat 是什么? - 3 SSL 是什么? Secure Sockets Layer,现在应该叫"TLS" ...
- 模拟登陆,selenium,线程池
一 . 模拟登陆案例(识别验证码) 1 . 打码平台 - 云打码 : www.yundama.com 使用步骤 : - 注册两个账户,普通用户和开发者用户 : - 登陆 普通用户查看余额 登陆开发 ...
- shell的面试题
在网上看到一道考shell的题--统计出一个文件夹下大小大于7MB的文件夹 好,我也来装一下深沉,个人觉得,这道题主要考的是对经常使用的linux的熟练程度(我不是很熟,哈哈),题目要统计,主要用到两 ...
- 如何使用ipv6
需要系统至少是Vista以上还有就是要问你们学校是否已经支持IPV6 从Windows Vista开始,IPv6在默认状态下已经安装并启用,无需额外配置.检测步骤开启浏览器窗口,输入以下域名访问本站首 ...
- webpack三种代码
在使用webpack时,主要有三种代码类型: 1.你或你的团队写的源码 2.第三方library或vendor代码 3.管理模块交互的runtime和manifest 什么是manifest文件? 通 ...
- 《avascript 高级程序设计(第三版)》 ---第二章 在HTML中使用Javascript
本章主要讲解了,怎么在HTML中使用: 1.<script src=""></script> 属性:defer="defer" 表示脚本 ...