zoukankan      html  css  js  c++  java
  • 第三课:JAVA反射机制

    基础的不想写啦,好了,直接上JAVA反射机制吧:

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

    JAVA类,他们的区别在于有不同的方法,不同的属性,类对象,就是用于描述这种类,都有什么属性,什么方法的。

    获取类对象有3种方式
    1. Class.forName() 括号里面是类的完整路径
    2. Hero.class
    3. new Hero().getClass()

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

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

     
    注意:获取类对象的时候,会导致类属性被初始化
     
    为Hero增加一个静态属性,并且在静态初始化块里进行初始化
     
    static String copyright;
    static {
    System.out.println("初始化 copyright");
    copyright = "版权由Riot Games公司所有";
    }
     

    无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。
     
    在对象方法前,加上修饰符synchronized ,同步对象是当前实例。
    那么如果在类方法前,加上修饰符 synchronized,同步对象是什么呢?
     
    当synchronized修饰静态方法的时候, 同步对象就是这个类的类对象

    如代码中的例子,当第一个线程进入method1的时候,需要占用TestReflection.class才能执行。

    第二个线程进入method2的时候,只有等第一个线程释放了对TestReflection.class的占用,才能够执行。 反推过来,第二个线程也是需要占用TestReflection.class。 那么TestReflection.class就是method2的同步对象。

    换句话说,静态方法被修饰为synchronized的时候,其同步对象就是当前类的类对象。
     
     TestReflection.java:
    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,所以结果很明显,锁住的是类对象。

    注意:

    package com.hero;
    
    import java.lang.reflect.Constructor;
    
    public class TestReflection3 {
    
    public static void main(String[] args) {
    //传统的使用new的方式创建对象
    /* Hero h1 =new Hero();
    h1.name = "teemo";
    System.out.println(h1);*/
    
    try {
    //使用反射的方式创建对象
    String className = "com.hero.Hero";
    //类对象
    Class pClass=Class.forName(className);
    //构造器,如果JAVA类只有有参的构造方法
    Constructor c= pClass.getConstructor(String.class,int.class);
    
    //通过构造器实例化
    Hero h2= (Hero) c.newInstance("a",1);
    h2.name="gareen";
    System.out.println(h2);
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
  • 相关阅读:
    屏蔽指定IP访问网站
    如何辨别一个网站是否是基于织梦搭建
    PC端访问移动站跳转PC站
    点击/swt/直接跳转商务通(1)
    页面加入视频
    dedecms教程:搜索页显示条数更改
    青蛙走迷宫问题(体力值)
    计算n的阶乘(n!)末尾0的个数
    Leetcode27--->Remove Element(移除数组中给定元素)
    Leetcode26--->Remove Duplicates from Sorted Array(从排序数组中移除相同的元素)
  • 原文地址:https://www.cnblogs.com/XJJD/p/7172982.html
Copyright © 2011-2022 走看看