1、动态语言和静态语言
-
动态语言
在运行时可以改变其结构的语言,例如新的函数、对象、已有的函数可以被删除或是其他结构上的变化。
-
静态语言
运行时不可改变结构的语言
-
Java不是动态语言,但Java可以被称为“准动态语言”,Java有一定的动态性,我们可以利用反射机制获得类似动态语言的特性
2、反射概述
-
Java Reflection
-
反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息(类名、类的接口、类的方法、类的属性等等),并能直接操作任何对象的内部属性及方法。
-
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个class对象),这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构
-
正常方式:
引入需要的包类名称 ---> new实例化 ---> 取得实例化对象
-
反射:
实例化对象 ---> getClass()方法 ---> 取得完整的包类名称
-
3、创建Class类的方式
-
方式一:通过getClass()获取
Class aClass = student.getClass();
-
方式二:通过forName获取
Class bClass = Class.forName("com.hmx.pojo.Student");
-
方式三:通过类名.class获取
Class cClass = Student.class;
-
方式四:通过子类的Class获取
Class personClass = student.getClass().getSuperclass();
-
方式五:基本内置类型的包装类通过Type属性可以获取Class类
Class typeClass = Integer.TYPE;
4、所有类型的Class对象
-
Class
Class c1 = Class.class;
//输出结果:class java.lang.Class
System.out.println(c1); -
类
Class c2 = Object.class;
//输出结果:class java.lang.Object
System.out.println(c2); -
接口
Class c3 = Comparable.class;
//输出结果:interface java.lang.Comparable
System.out.println(c3); -
注解
Class c4 = Override.class;
//输出结果:interface java.lang.Override
System.out.println(c4); -
基本数据类型
Class c5 = Integer.class;
//输出结果:class java.lang.Integer
System.out.println(c5); -
一维数组
Class c6 = String[].class;
//输出结果:class [Ljava.lang.String;
System.out.println(c6); -
二维数组
Class c7 = String[][].class;
//输出结果:class [[Ljava.lang.String;
System.out.println(c7); -
枚举
Class c8 = ElementType.class;
//输出结果:class java.lang.annotation.ElementType
System.out.println(c8); -
void
Class c9 = void.class;
//输出结果:void
System.out.println(c9);
5、类加载器
-
类加载器的作用
-
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后在堆中生成一个代表这个类的 java.lang.Class 对象,作为方法区中类数据的访问入口
-
-
分类
-
系统类加载器:最常用的加载器,主要负责加载classpath所指定的位置的类或者是jar文档
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//输出结果为:sun.misc.Launcher$AppClassLoader@18b4aac2
System.out.println(systemClassLoader); -
扩展类加载器:主要加载
%JAVA_HOME%/jre/lib/ext
,此路径下的所有classes目录以及java.ext.dirs
系统变量指定的路径中类库ClassLoader extClassLoader = systemClassLoader.getParent();
//输出结果为:sun.misc.Launcher$ExtClassLoader@1540e19d
System.out.println(extClassLoader); -
引导类加载器:C++编写的,JVM自带的类加载器,负责Java平台核心库,用来装载核心类库,该加载器无法直接获取
ClassLoader parent = extClassLoader.getParent();
//输出结果为:null
System.out.println(parent);
-
6、类加载内存分析
以下面这段代码为例讲解
public class Test03 {
public static void main(String[] args) {
AAA aaa = new AAA();
System.out.println(AAA.num);
}
}
class AAA{
static {
System.out.println("类AAA的静态代码代码块");
}
static int num = 100;
public AAA() {
System.out.println("类AAA的构造方法");
}
}
-
第一步:加载
-
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象
-