反射----2
Class类对象 Class对象的获取方式
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. Class类对象
1). Class类描述的事物
(1). Class类描述的事物
[1]. Java对字节码文件(.class) 进行了抽象,用Class类来描述字节码文件
[2]. 学习反射的核心:就是获取字节码文件中的内容。
2). Class类对象的作用
Class类可以获取字节码文件中的所有信息
[1].反射依靠的元素:Class类【Class类可以获取字节码文件中的所有信息】
[2]. 想要对一个类文件解剖,只要获取到该类的字节码文件对象,即Class对象即可。
[3]. Class类的源码声明:
public final class Class<T>…{…}
【注意】
{1}. Class类是一个泛型类,类型参数T表示某个Class类对象所属于哪一个类
{2}. final修饰Class类,说明Class类不能被继承。
[4]. Class类不能new对象。Class clazz =newClass();是绝对错误的!!!!
3). 获取Class类对象的三种途径
实体类代码:
public class Person {
private int age;
private String name;
public Person(String name, int age){
super();
this.age =age;
this.name =name;
System.out.println("Person param run..."+ this.name+":" + this.age);
}
public Person(){
System.out.println("Person run...");
}
}
(1). 非静态方法:getClass()
[1]. 通过Object类的getClass()方法来获取Class类对象
【示例代码】
//Way1. 根据一个类的具体对象获取Class类对象
public static void getClassObject_1(){
Personp =new Person();
Classclazz =p.getClass();
Personp1 =new Person();
Classclazz1 =p1.getClass();
sop(clazz== clazz1);
}
打印结果:
[2]. sop(clazz == clazz1);打印结果是true说明:一个类无论有多少个对象,他们的Class对象是同一个,也就是对应同一份字节码文件。
[3]. 缺点:getClass获取Class类对象的需要明确具体的类并建立相应的对象。这种方式十分麻烦。
(2). 静态属性:class
[1]. 通过任意数据类型的一个静态属性“class”来获取Class类对象
【示例代码】
//Way2. 根据一个类的静态属性class来获取Class对象
public static void getClassObject_2(){
Classclazz =Person.class;
Classclazz1 =Person.class;
sop(clazz==clazz1);
}
打印结果:true
[2]. 缺点:相对简单,但是还是要类中的静态成员,扩展性差
(3). 静态方法:Class.forName()
[1]. 通过Class类forName() + 某个类的全类名来获取Class类对象
【示例代码】
//Way3. 采用Class的静态方法forName获取这个类的Class对象
public static void getClassObject_3(){
try{
//一定要给出这个类的全名:包名 +类名
Classclazz =Class.forName("cn.itcast.bean.Person");
sop(clazz);
}catch(ClassNotFoundException e){
sop(e.toString());
}
}
打印结果:class cn.itcast.bean.Person
[2]. 优点:仅仅需要以字符串形式给出的类的全名即可获取这个类的Class对象,这种方式最为常用,最为方便
[3]. 面试:forName()方法的作用是什么?
{1}. forName( )作用:是返回某个类的字节码文件对象,也就是Class对象。
{2}. forName( )返回字节码文件的两种方式:
{2}1. 如果这份字节码文件已经被加载,此时forName()直接返回
{2}2. 如果JVM 没有找到要加载的字节码文件,那么JVM就 指示类加载器去 加载该字节码文件。JVM将加载完的字节码放到自己的缓存中,再返回。4). Class对象的常用方法
(1). 判断指定的Class对象是否表示一个基本类型
public native boolean isPrimitive(); ---- 本地化方法
(2). 判断指定的Class对象是否表示一个数组类
public native boolean isArray(); ---- 本地化方法
【举例】
System.out.println(int[].class.isPrimitive()); //打印false
System.out.println(int[].class.isArray()); //打印true
(3). 获取Class对象表示的基本信息
[1]. 原型:public String getName();
[2]. 描述:以String的形式返回此Class对象所表示的实体名称
其中实体包括:类、接口、数组类、基本类型 或void
【举例】
System.out.println(Integer.class.getName());
打印结果:java.lang.Integer
2. Java预定义Class实例对象
(1). 前八种预定义Class实例对象
[1].八种基本数据类对应八个Class实例对象
byte.class,short.class,int.class,long.class,char.class,boolean.class,float.class,double.class
[2]. 基本数据类型的Class实例对象和其对应的包装类的Class实例对象
{1}. 基本数据类型的Class实例对象并不是对应包装类对象的Class对象,两者不是一回事
【举例】
System.out.println(int.class == Integer.class); //打印false
{2}. 包装类 中封装了基本数据类型的Class对象作为其成员全局常量
以Integer类为例:
public static final Class<Integer> TYPE
= (Class<Integer>) Class.getPrimitiveClass("int");
【举例】
System.out.println(Integer.TYPE ==int.class);// 打印true
(2). 第九种预定义的Class实例对象
void类型对应的Class对象是第九种预定义对象:void.class
【注意】数组也是一种数据类型。只要是数据类型,就必须有对应的Class对象。