Java的类与Class
- RTTI(RunTime Type Identification)运行时类型识别
- 一个Class对象就是类的说明书
- JVM根据这个说明书创建出来一个类的实例
- instanceof
- 强制类型转换
Object类
- public方法:
- clone
- equals
- finalize
- getClass
- hashCode
- notify
- notifyAll
- toString
- wait
Class对象的生命周期
- 在第一次被使用时被加载
Class和Classloader
1. Classloader负责从外部系统中加载一个类
- 这个类对应的Java文件并不一定需要存在
- 可以从网络获取字节流,文件的本质是字节流
- 可以动态在内存中生成(Classloader)
- 这个字节码并不一定需要存在
-
2. Classloader的双亲委派加载模型
外部系统是不安全的,完全可以伪造java.lang.*类
- Classloader loadClass会先查看parent有没有加载,父类加载了自己就不会加载
内置类都会由顶端的类加载器加载,所以伪造java.lang.*类是无效的
3. Java语言规范与Java虚拟机规范
class的文件可以不由Java文件生成,所以JVM的运行可以不必依赖Java文件
- Java语言和虚拟机的联系其实就是字节码,但是字节码可以不由Java语言生产
- 这种分离提供了在JVM上运行其他语言的可能
- Java Language Specification(JLS),Java语言规范
- Java Virtual Machine Specification(JVMS),Java虚拟机规范
反射
- 为什么叫反射?
假如想:
- 根据参数动态创建一个对象?
- 根据参数动态调取一个方法?
- 根据参数动态获取一个属性?
// 根据参数动态创建一个对象
// 反射代码编写时,并不知道未来要创建的对象是一个什么
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
String className = args[0];
Class c = Class.forName(className);
Object obj = c.getConstructor().newInstance();
}
// 动态调用方法
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String methodName = args[0];
MyObj obj = new MyObj();
obj.getClass().getMethod(arg[0]).invoke(obj);
}
Class
- Class.forName()
- Method
- Method.invoke
- Field
- Field.get
- 反射无处不在
- Spring源码分析