不管是mybaits,还是hibernate或者是其他大多数框架,总提到映射。映射说到底就是关于Class类的运用
A.什么是反射(映射)
1.指的是可以于运行时加载,探知,使用编译期间完全未知的类。
2.程序在运行状态下可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法,对于任何一个对象都能够调用他的方法和属性
核心就是得到Class类的代码 Class c = class.forName("zhuzihan.test"); 还有其他两种得到class的方法
3.加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象),这个类就包含了完整的类的结构信息。我们可以通过这个Class对象看到类的结构(包括注解),就像一个镜子,所以我们形象的称其为反射。
B.什么是Class类
java语言在实例化一个对象的时候,经过加载,连接(验证,准备,解析),和初始化3过程。在加载过程中会由jvm生产一个java.lang.Class类,里面包括了所有这个类的一切结构信息,Class就是这个类的蓝本草图,最主要是java是一个面向对象的语言,一切都是对象,但是java并不知道这个对象是什么对象,比如int型,jvm并不知道这个是什么,但是jvm会通过int的class类来知道这个是一个int型(所以任何int对应的class都是一个蓝本,如下图测试)
获得Class的方法, Test test=new Test();
1, test.getClass(); 2, Test.class 3. Class.forName(类名)
C:类的加载过程
1 package testone; 2 3 public class StaticTest { 4 5 public int x = 5; 6 static private int y = 6; 7 8 public StaticTest() { 9 System.out.println("创建staicTest"); 10 staticFunction(); 11 } 12 13 public StaticTest(int x) { 14 super(); 15 this.x = x; 16 System.out.println(x); 17 } 18 19 public void notStaticFunction() { 20 System.out.println("非静态方法"); 21 } 22 23 static { 24 System.out.println("初始化staticTest"); 25 /* 26 * x不是静态的,在初始化中方法区中初始化的是类的静态变量,静态块,静态方法,类的代码 27 */ 28 // System.out.println(x); 29 System.out.println(y); 30 staticFunction(); 31 StaticTest staticTest = new StaticTest(1); 32 staticTest.notStaticFunction(); 33 34 } 35 36 public static int staticFunction() { 37 System.out.println("类的静态方法"); 38 /* 39 * 不注释掉这个的话,在main方法中就不会有初始化A的句子,意思是初始化是在第一次用到的时候初始化 而且静态代码块永远在最前面, 40 */ 41 // A a = new A(); 42 // System.out.println(a.width); 43 return 1; 44 } 45 46 public static void main(String[] args) { 47 System.out.println("进入main"); 48 A a = new A(); 49 System.out.println(a.width); 50 B b = new B(); 51 staticFunction(); 52 } 53 54 static class B { 55 public B() { 56 System.out.println("创建B"); 57 } 58 59 static { 60 System.out.println("初始化B"); 61 } 62 63 public void Desc() { 64 System.out.println("你好"); 65 } 66 } 67 68 } 69 70 class A { 71 public static int width = 100; 72 73 static { 74 System.out.println("静态初始化类A"); 75 width = 200; 76 } 77 78 public A() { 79 System.out.println("创建类A"); 80 } 81 }
上面代码是具体的加载过程详解 下面是部分代码
运行结果:静态初始化A
创建A类的对象
200(虽然先初始化读到的是200但是先读完所有数据后,还是会按照正常顺序执行一次)
其实在初始化不管他的默认顺序如何,但是第一轮初始化肯定会初始化完成的是静态的一切,稍后就是
方法名,类名。总之都会加载完,所以在静态中调用非静态也是可以的(类似于先加载的静态方法块中找到了一个类,他就会马上强制提前去找这个类的名字,扎到之后又按照之前的顺序把这个类的一切初始化了)