第三课:JAVA反射机制
基础的不想写啦,好了,直接上JAVA反射机制吧:
类对象概念: 所有的类,都存在一个类对象,这个类对象用于提供类层面的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。
JAVA类,他们的区别在于有不同的方法,不同的属性,类对象,就是用于描述这种类,都有什么属性,什么方法的。
获取类对象有3种方式
1. Class.forName() 括号里面是类的完整路径
2. Hero.class
3. new Hero().getClass()
在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。
注: 准确的讲是一个ClassLoader下,一种类,只会有一个类对象存在。通常一个JVM下,只会有一个ClassLoader。因为还没有引入ClassLoader概念, 所以暂时不展开了。


无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。


那么如果在类方法前,加上修饰符 synchronized,同步对象是什么呢?
如代码中的例子,当第一个线程进入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,所以结果很明显,锁住的是类对象。
注意:
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();
}
}
}
第三课:JAVA反射机制的更多相关文章
- 5. Java反射机制
Java反射机制 问题: 在运行时,对一个JAVA类,能否知道属性和方法:能否调用它的任意方法? 答案是可以的,JAVA提供一种反射机制可以实现. 目录 什么是JAVA的反射机制 JDK中提供的R ...
- java反射机制(2)
首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Refle ...
- Java反射机制详解(1) -反射定义
首先,我们在开始前提出一个问题: 1.在运行时,对于一个java类,能否知道属性和方法:能否去调用它的任意方法? 答案是肯定的. 本节所有目录如下: 什么是JAVA的反射机制 JDK中提供的Refle ...
- Java反射机制能够获取的信息,与应用
一.什么是Java反射机制? [1]反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法: [2]对于任意一个对象,都能够调用它的任意一个属性和方法: 像这种动态获取类的信息以及动 ...
- Java反射机制 —— 简单了解
一.概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- Java 基础之详解 Java 反射机制
一.什么是 Java 的反射机制? 反射(Reflection)是Java的高级特性之一,是框架实现的基础,定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: ...
- Java反射机制(创建Class对象的三种方式)
1:SUN提供的反射机制的类: java.lang.Class<T> java.lang.reflect.Constructor<T> java.lang.reflect.Fi ...
- Java反射机制demo(三)—获取类中的构造函数
Java反射机制demo(三)—获取类中的构造函数 1,获取类中所有的构造函数 如下面的代码中所示,这个类中显式的构造函数有五个. 空构造: public UserInfo() 带参构造有四个: pu ...
- Java反射机制剖析(三)-简单谈谈动态代理
通过Java反射机制剖析(一)和Java反射机制剖析(二)的学习,已经对反射有了一定的了解,这一篇通过动态代理的例子来进一步学习反射机制. 1. 代理模式 代理模式就是为其他对象提供一种代理来 ...
随机推荐
- shell中判断是否是月末的方法
判断今天是不是一月的最后一天: 如果$(TZ=IST-32 date +%d)是1就是月末了.
- 《Lua程序设计》9.1 协同程序基础 学习笔记
协同程序(coroutine)与线程(thread)差不多,也就是一条执行序列,拥有自己独立的栈.局部变量和指令指针,同时又与其他协同程序共享全局变量和其他大部分东西.从概念上讲线程与协同程序的主要区 ...
- HTML-锚点-JS跳转锚点
window.location.hash使用说明,这篇写的挺详细的 http://www.cnblogs.com/nifengs/p/5104763.html a标签的话是 name,div呢是id, ...
- 怎么修改wamp的本地时间
最近配置了一台wamp环境的服务器,但发现时间与本地时间是地区别的,并且 利用time获取的时间再利用date显示有时差的,下面我们一起来导致原因与解决办法. 如果date时间不一致可以使用date_ ...
- 为什么有这么多 Python版本
Python是出类拔萃的 然而,这是一句非常模棱两可的话.这里的"Python"到底指的是什么? 是Python的抽象接口吗?是Python的通用实现CPython吗(不要把CPy ...
- 【HIbernate异常】could not initialize proxy - no Session (已解决)
异常信息: org.hibernate.LazyInitializationException: could not initialize proxy - no Session 解决方法: 用 get ...
- ERROR 1045 (28000): Access denied for user 'mycat'@'localhost' (using password: YES)
创建用户: mysql> grant all on db1.* to mycat@'%' identified by '123456'; Query OK, 0 rows affected (0 ...
- JiraRemoteUserAuth
配置Jira7.x版本使用REMOTE_USER的HTTP Header方式登录: 前提是已经安装好了JIRA,并且前端使用apache或者nginx拦截对应的地址进行认证,认证之后访问对应的应用的时 ...
- wps插件开发中com组件权限
需要对wps写一个小的插件,也就是几行代码的事情,但却碰到了一个坑 wps中的com组件的调用和MSoffice非常的相似,几乎只需要把包的头修改一下就可以用了. 比如开发wps文档的插件,需要引用 ...
- 【CF886D】Restoration of string 乱搞
[CF886D]Restoration of string 题意:对于给定的一个母串,定义一个字符串是出现频率最多的,当且仅当它在母串中出现的次数最多(可以有多个出现次数最多的,出现的位置可以重叠). ...