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

来源: <http://www.cnblogs.com/xuemaxiongfeng/archive/2013/08/24/3278859.html>

来自为知笔记(Wiz)

时间: 2024-10-23 01:02:34

JAVA类型信息——Class对象(转载)的相关文章

Java基础 -- 深入理解Java类型信息(Class对象)与反射机制

一 RTTI概念 认识Claa对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RTTI的说法则是源于<Thinking in Java>一书,其作用是在运行时识别一个对象的类型和类的信息,这里分两种: 传统的”RTTI”:它假定我们在编译期已知道了所有类型(在没有反射机制创建和使用类对象时,一般都是编译期已确定其类型,如new对象时该类必须已定义好): 反射机制,它允许我们在运

深入理解Java类型信息(Class对象)与反射机制(干货)

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/70768369 出自[zejian的博客] 本篇主要是深入对Java中的Class对象进行分析,这对后续深入理解反射技术非常重要,这篇有点偏向内功类文章,主要内容如下: 深入理解Class对象 RRTI的概念以及Class对象作用 Class对象的加载及其获取方式 Class对象的加载 ClassforName方法 Class字面常

深入理解Java类型信息(Class对象)与反射机制

深入理解Class对象 RRTI的概念以及Class对象作用 认识Class对象之前,先来了解一个概念,RTTI(Run-Time Type Identification)运行时类型识别,对于这个词一直是 C++ 中的概念,至于Java中出现RRTI的说法则是源于<Thinking in Java>一书,其作用是在运行时识别一个对象的类型和类的信息,这里分两种:传统的"RRTI",它假定我们在编译期已知道了所有类型(在没有反射机制创建和使用类对象时,一般都是编译期已确定其类

Thinking in Java -- 类型信息RTTI

Thinking in Java – 类型信息 个人感觉 java 中的比較难的部分了,在看了些netty源代码发现事实上这块很实用. 这章重点是RTTI和反射.先说下自己的理解 RTTI是执行时识别.在c++中是用virtual来实现的,在编译期会忽略对象的详细类型信息,假定我们已经知道,并在执行时详细识别. Java反射机制实在执行状态中,对于随意一个类,都能够知道这个类的全部属性和方法.对于随意一个对象.都能够调用它的随意一个方法和属性,这样的动态获取的信息以及动态调用对 象的方法的功能称

Java类型信息与应用--动态代理

Java类型信息与应用--动态代理 本文结构 一.前言 二.为什么需要RTTI 三.RTTI在java中的工作原理 四.类型转化前先做检测 五.动态代理 六.动态代理的不足 一.前言 运行时信息使你可以在程序运行时发现和使用类型信息 Java在运行时识别对象和类的信息的方式: 1.一种是RTTI,它假定我们在编译时已经知道了所有的类型. 2.另一种是"反射"机制,它允许我们在运行时发现和使用类的信息. 这带来的好处是,你可以在程序运行时发现和使用类型信息 二.为什么需要RTTI 以多态

【Java核心技术】类型信息(Class对象 反射 动态代理)

1 Class对象 理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息.Class对象就是用来创建所有"常规"对象的,Java使用Class对象来执行RTTI,即使你正在执行的是类似类型转换这样的操作. 每个类都会产生一个对应的Class对象,也就是保存在.class文件.所有类都是在对其第一次使用时,动态加载到JVM的,当程序创建一个对类的静态成员的引用时,就会加载这个类.Class对象仅在需要的时候才会

java类型信息之一---Class

RTTI RunTime Type Info 多态 在面向对象语言中,接口的多种不同的实现方式即为多态. 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. Charlie Calverts对多态的描述--多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后, 父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作. java中,父类型引用可以指向子类型对象. Shape shape = new Triangle();

九、java中类型信息

一.什么是类型信息? 简单的理解 ,“类型信息”就是一种机制, java中用这种机制来实现: 在程序运行过程中发现和使用“类”信息. java的类型信息主要有两块组成:RTTI和反射. 二.什么是RTTI? RTTI,全称是Run-Time Type Information  ,名字的含义是在运行时识别一个对象的类型. 1.Class对象 java中用一个特殊的对象Class, 通过它来执行其RTTI(这是一种思想, 用一个Class来表示所有类型对象,通过具体的Class里面的属性再来区分到底

《JAVA编程思想》学习笔记——第十四章 类型信息

运行时类型信息使得你可以在程序运行时发现和使用类型信息. 主要有两种方式:一种是"传统的"RTTI, 它假定我们在编译时已经知道了所有的类型;另一种是"反射"机制,它允许我们在运行时发现和使用类的信息. Class对象 类是程序的一部分,每个类都有一个Class对象.换言之,每当编写并且编译一个新类,就会产生一个Class对象(更恰当的说,是被保存在一个同名的.class文件中).为了生成这个类的对象,运行这个程序的Java虚拟机(JVM)将使用被称为"类