java基础-反射1(类型信息,Class对象简介,Class对象初始化)
来源:互联网 发布:虎门三通淘宝培训在那 编辑:程序博客网 时间:2024/06/06 09:08
Java基础-反射1(反射基础,运行时类型信息,Class对象简介)
在学习反射之前,先来了解一下类型信息,类型信息就是JAVA类的一些信息,包括(包,方法,属性等),运行时类型信息可以让你在程序运行时了解类的信息并且使用类,那么如何在运行时获取类的信息?在JAVA中有两种方式:
- 传统的RTTI
- 反射
RTTI (Run-Time Type identification)
传统的RTTI的使用是假定我们在编译时就已经知道了类的信息。先来看一个例子:有一个People的抽象类,然后American类和Chinese类继承至People如下:
public abstract class People { public abstract void say();}
public class American extends People { @Override public void say() { System.out.println("Americaen say: hello"); }}
public class Chinese extends People { @Override public void say() { System.out.println("中国人 说: 你好"); }}
public class Test { public static void main(String agrs[]){ List<People> peoples= new ArrayList<>(); peoples.add(new American()); peoples.add(new Chinese()); for (int i = 0 ;i <peoples.size();i++){ peoples.get(i).say(); } }}
这是一个简单的类的继承例子,People是父类,American 和Chinese 是子类,在Test中我们创建一个List,放入American和Chinese,然后我们取出,调用say()方法.
在这里我们List中定义需要放的类型是父类People,而不是子类,面向对象的目的是让程序只操作父类而不是子类,但是我们实际上往List中添加的类型是子类(American,Chinese),这里就发生了向上转型(子类对象赋值给父类引用)但是我们在调用People的say()方法时却又打印出子类的信息(这就是多态)
下面我们来看把对象从List中取出来的代码:
ArrayList底层是通过数组实现的 下面是ArryList源码中的其中一个构造方法
transient Object[] elementData; public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
通过源码可以看出 elementData 是一个Object 数组。所以
List peoples= new ArrayList<>(); 其实是储存的Object[]数组,但是当我们从List中取出来时,如下面代码:
for (int i = 0 ;i <peoples.size();i++){ peoples.get(i).say(); }
当我们从List中取出来时却又表现出People的特点,那是因为我们从List<People> peoples
中取出来时自动将Object转化为了People(向下转型,相当于People people = (People)object) 这就是RTTI的最基本的使用形式:在运行时进行类型检查因为我们在编译时已经知道List<People> peoples
储存的都是People。所以在我们从容器中取出元素时系统自动会将Object转化为People。
那么RTTI是如何工作的喃?要理解RTTI的工作原理就必须要类型信息在运行时如何表示的。
Class对象简介
java 在运行时表示类型信息是通过class这个特殊对象来完成的,
class对象属于Class类,Class类用来表示一般类的信息,所以class对象包含了与类相关的信息,它主要有以下几个特点:
- 每个类都有一个与其相关的Class对象。
- Class对象含有与其相关类的类信息。
- Class对象用来创建与其相关类的“常规对象“
- Class对象保存在与其同名的.class文件中。
那么Class对象是如何产生的喃?
Class对象是通过类加载器加载的,并且只有在第一次使用类时才会被加载。
当使用一个类时,JVM的类加载器会先检查这个类的class对象是否已经被加载,如果没有被加载,则查找同名的.class文件。如果一旦发现类的class对象已经被加载到内存了,则使用这个class对象来创建这个类的所有对象。
那么如何获取Class对象?
Class对象的获取
下面看下这个例子
public class Dog { static { System.out.println("狗"); }}
public class Cat { static { System.out.println("猫"); }}
public class People { static { System.out.println("人"); }}
public class Test { public static void main(String agrs[]){ try { //获取Class 的第一种方法 Class catClass= Class.forName("com.hbcode.Test.Cat"); Dog dog1 = new Dog(); //获取Class 的第二种方法 Class dog =dog1.getClass(); //获取Class 的第三种方法 Class people =People.class; } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
上面就是获取类的class对象的三种方法,下面我们看下打印的信息
我们发现没有打印出来“人”那是因为使用.class来获取类的class对象并不会初始化类的class对象,实际上在获取class对象时做了一下三步:
- 类的加载:由类加载器执行,根据类名查找.class文件,并从中创建一个class对象
- 类的链接:验证.class文件(字节码文件)看其结构是否完整,并且为静态域分配空间。
- 类的初始化:如果类有父类则初始化父类,执行父类的静态初始化块,和静态初始化器,然后执行自己的。
延伸:笔试题,变量的初始化顺序
根据《java编程思想》一书上面的讲解,类的初始化其实是被延迟到了对静态方法的引用(构造函数也是隐式的静态方法)或者是非常数的静态域进行引用。
从上面可以看出Class.forName()
其实就是调用的是类的静态函数可以被初始化。创建对象 new 对象时其实也是对构造函数(隐式的静态方法)的调用。
现在我们获取到了class对象,就可以获取其相对应的类型信息了,下一篇文章我们就来通过class对象来获取类的类型信息,并且通过反射来操作类
- java基础-反射1(类型信息,Class对象简介,Class对象初始化)
- java基础-反射2(反射,反射操作对象,Class对象的使用,类型信息的获取)
- 深入理解Java类型信息(Class对象)与反射机制
- 深入理解Java类型信息(Class对象)与反射机制
- 深入理解Java类型信息(Class对象)与反射机制
- 深入理解Java类型信息(Class对象)与反射机制
- Java反射基础(一)--Class对象获取
- java类型信息—class对象
- Java Class对象简介
- Java RTTI(类型信息)(.class 类对象)
- Java编程思想之类型信息(Class对象)
- 类型信息之Class对象
- 类型信息之Class对象
- java基础-Class对象
- Java反射(一) : 获取Class对象
- Java反射(一)Class类对象
- 类型信息:反射-Class
- java 类型信息(RTTI) 中 Class对象的理解
- El表达式不起作用
- eclipse中使用maven的手段
- C++IO库--fstream和stringstream
- redis 强制关闭Redis快照导致不能持久化解决方案
- 关于ArrayList的5道面试题
- java基础-反射1(类型信息,Class对象简介,Class对象初始化)
- 【十八掌●武功篇】第八掌:HBase之安装与集成
- 腐蚀、膨胀、开运算、闭运算
- Dijkstra算法---模板
- HDU 4310 Hero【贪心】
- Apache httpd 安装启动demo(Window版)
- 第十四周项目1— 验证算法
- RxJava2笔记(2)—线程切换基础
- 第十三周项目三