反射机制 获取类对象

JAVA反射机制实在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为JAVA反射机制。
        要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象。
        通俗来讲,反射就是通过class文件对象,去使用该文件中的成员变量、构造方法、成员方法。
        Class类:
                成员变量:Field
                构造函数:Constructor
                成员方法:Method

类对象概念: 所有的类,都存在一个 类对象,这个类对象用于提供 类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。

  • 什么是类对象

    在理解类对象之前,先说我们熟悉的对象之间的区别:
    garen和teemo都是Hero对象,他们的区别在于,各自有不同的名称,血量,伤害值。


    然后说说类之间的区别
    Hero和Item都是类,他们的区别在于有不同的方法,不同的属性。


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

  • 获取类对象

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


    在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。
    在开发中一般使用第三种,因为第三种是一个字符串,而不是一个具体的类名。这样我们就可以把这样的字符串配置到配置文件中。

    注: 准确的讲是一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个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(pClass1==pClass3);
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }
  • 获取类对象的时候,会导致类属性被初始化

    为Hero增加一个静态属性,并且在静态初始化块里进行初始化,参考 类属性初始化。 

    static String copyright;
    static {
        System.out.println("初始化 copyright");
        copyright = "版权由Riot Games公司所有";
    }

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



    package charactor;
     
    public class Hero {
        public String name;
        public float hp;
        public int damage;
        public int id;
     
        static String copyright;
     
        static {
            System.out.println("初始化 copyright");
            copyright = "版权由Riot Games公司所有";
        }
     
    }
    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();
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
    }
  • 在静态方法上加synchronized,同步对象是什么

    在对象方法前,加上修饰符synchronized ,同步对象是当前实例。
    那么如果在类方法前,加上修饰符 synchronized,同步对象是什么呢?

    public static void method1() {
     
           synchronized (TestReflection.class) {
               // 对于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();
           }
     
       }







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值