首页 > 代码库 > 第三课:JAVA反射机制
第三课:JAVA反射机制
基础的不想写啦,好了,直接上JAVA反射机制吧:
类对象概念: 所有的类,都存在一个类对象,这个类对象用于提供类层面的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。
JAVA类,他们的区别在于有不同的方法,不同的属性,类对象,就是用于描述这种类,都有什么属性,什么方法的。
获取类对象有3种方式
1. Class.forName() 括号里面是类的完整路径
2. Hero.class
3. new Hero().getClass()
在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。
注: 准确的讲是一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader。因为还没有引入ClassLoader概念, 所以暂时不展开了。
无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。
如代码中的例子,当第一个线程进入method1的时候,需要占用TestReflection.class才能执行。
第二个线程进入method2的时候,只有等第一个线程释放了对TestReflection.class的占用,才能够执行。 反推过来,第二个线程也是需要占用TestReflection.class。 那么TestReflection.class就是method2的同步对象。
换句话说,静态方法被修饰为synchronized的时候,其同步对象就是当前类的类对象。
package com.hero;
public class TestReflection {
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread() {
public void run() {
// 调用method1
TestReflection.method1();
}
};
t1.setName("第一个线程");
t1.start();
// 保证第一个线程先调用method1
Thread.sleep(1000);
Thread t2 = new Thread() {
public void run() {
// 调用method2
TestReflection.method2();
}
};
t2.setName("第二个线程");
t2.start();
}
public synchronized static void method1() {
// 对于method1而言,同步对象是TestReflection.class,只有占用TestReflection.class才可以执行到这里
System.out.println(Thread.currentThread().getName() + " 进入了method1方法");
try {
System.out.println("运行5秒");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void method2() {
// 对于mehotd2而言,必然有个同步对象,通过观察发现,当某个线程在method1中,占用了TestReflection.class之后
// 就无法进入method2,推断出,method2的同步对象,就是TestReflection.class
System.out.println(Thread.currentThread().getName() + " 进入了method2方法");
try {
System.out.println("运行5秒");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TestReflection2.java:
public static synchronized void method2() {
// 对于mehotd2而言,必然有个同步对象,通过观察发现,当某个线程在method1中,占用了TestReflection.class之后
// 就无法进入method2,推断出,method2的同步对象,就是TestReflection.class
System.out.println(Thread.currentThread().getName() + " 进入了method2方法");
try {
System.out.println("运行5秒");
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出为:
第一个线程 进入了method1方法
运行5秒
(中间停顿了1秒)
第二个线程 进入了method2方法
运行5秒
然而当我把TestReflection2.method2();改为TestReflection.method2();的时候,停顿时间为6s,所以结果很明显,锁住的是类对象。
第三课:JAVA反射机制