Java的反射机制

转自:http://how2j.cn/k/reflection/reflection-class/108.html

一、什么是类对象

  类对象,就是用于描述这种类,都有什么属性,什么方法的。


二、获取类对象

获取类对象有3种方式
1. Class.forName
2. Hero.class
3. new Hero().getClass()

在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。

注: 准确的讲是一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader。因为还没有引入ClassLoader概念, 所以暂时不展开了。

package reflection;

import charactor.Hero;

public class TestReflection {

    public static void main(String [] args){
        String className="charactor.Hero";
        try {
            Class pClass1=Class.forName(className);
            Class pClass2= Hero.class;
            Class pClass3=new Hero().getClass();
            System.out.println(pClass1==pClass2);
            System.out.println(pClass2==pClass3);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}


三、获取类对象的时候,会导致类属性被初始化。

为Hero增加一个静态属性,并且在静态初始化块里进行初始化,参考 类属性初始化。 
 
static String copyright;
static {
    System.out.println("初始化 copyright");
    copyright = "版权由Riot Games公司所有";
}

  无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)


四、在静态方法上加synchronized,同步对象是什么

  当synchronized修饰静态方法的时候, 同步对象就是这个类的类对象。
  如代码中的例子,当第一个线程进入method1的时候,需要占用TestReflectionStatic.class才能执行。
  第二个线程进入method2的时候进去不,只有等第一个线程释放了对TestReflectionStatic.class的占用,才能够执行。 反推过来,第二个线程也是需要占用TestReflectionStatic.class。 那么TestReflectionStatic.class就是method2的同步对象。
  换句话说,静态方法被修饰为synchronized的时候,其同步对象就是当前类的类对象。

package reflection;

public class TestReflectionStatic {

    public static void main(String [] args) throws InterruptedException {
        Thread thread1=new Thread(){
            public void run(){
                TestReflectionStatic.method1();
            }
        };
        thread1.setName("第一个线程");
        thread1.start();
        
        //保证第一个线程先调用
        Thread.sleep(1000);

        Thread thread2=new Thread(){
            public void run(){
                TestReflectionStatic.method2();
            }
        };
        thread2.setName("第二个线程");
        thread2.start();
    }

    public static void method1(){
        synchronized (TestReflectionStatic.class){
            System.out.println(Thread.currentThread().getName()+"进入了method1方法");
            try {
                System.out.println("运行5秒");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /*
    对于method2而言,必然有个同步对象,通过观察发现,
    当某个线程在method1中,占用了TestReflectionStatic.class之后
    就无法进入method2,推断出,method2的同步对象,就是TestReflection.class
     */
    public static synchronized void method2(){
        try {
            System.out.println("运行5秒");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值