Class对象
来源:互联网 发布:灰原哀 知乎 编辑:程序博客网 时间:2024/05/17 00:57
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;
abstractclass Shapes{
void draw() {System.out.println(this + ".draw()");}
abstractpublic String toString();
}
class Circleextends Shapes{
public String toString() {return"Circle";}
}
class Triangleextends Shapes{
public String toString() {return"Triangle";}
}
class Squareextends Shapes{
public String toString() {return"Square";}
}
class Test{
publicstatic List<Shapes> getList(){
List<Shapes> list_aShapes = Arrays.asList(new Circle() ,new Square(), new Triangle());
return list_aShapes;
}
}
publicclass Shape {
publicstatic 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
- Class对象
- Class对象
- Class 对象
- class对象
- Class对象
- Class对象
- Class对象
- Class对象
- Class对象
- Class对象
- Class对象
- Class对象
- Class对象
- Class对象
- [Java] Class对象
- 产生inner class对象
- Class对象测试
- class 对象对齐
- 【JS 设计模式 】用组合模式来实现树形导航--JS代码结构思路分析(二)
- JAVA 如何使用 MD5 和SHA1进行数据加密
- git分支管理命令
- [heartbeat]基于httpclient的文件可配置的心跳检测应用
- java-一维数组的随机赋值
- Class对象
- Linux常用快捷键
- [疯狂Java]I/O:标准流重定向、JVM读写其它进程数据
- 专题二 第十二道题
- Linux的inode的理解
- [翻译]Java Garbage Collection Basics Java 垃圾回收基础 之2 Java 技术与JVM
- 第九周上机时间项目——项目2—我的数组类
- 他们在一起了(全区名和全区号)
- tomcat配置静态访问路径