第三课: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. 代理模式 代理模式就是为其他对象提供一种代理来 ...
随机推荐
- 安装.NET Framework 3.5
https://www.microsoft.com/zh-CN/download/details.aspx?id=22 https://docs.microsoft.com/zh-cn/dotnet/ ...
- IntelliJ IDEA:Field injection is not recommended
使用IntelliJ IDEA进行开发的时候,code analyze的时候会出现提示“Field injection is not recommended”. stackoverflow上有篇回答: ...
- Android设计和开发系列第二篇:Navigation Drawer(Design)
Navigation Drawer Creating a Navigation Drawer The navigation drawer is a panel that transitions in ...
- linux 文件编码问题
iconv -f UTF- -t gb18030 file_input -o file_output 上述命令不一定有用. 大概了解下文件编码,和vim里面的编码情况. 1 字符编码基础知识 字符编码 ...
- python中字符串(str)的常用处理方法
str='python String function' 生成字符串变量str='python String function' 字符串长度获取:len(str)例:print '%s length= ...
- Android 性能分析工具 TraceView
官方地址 http://developer.android.com/tools/debugging/debugging-tracing.html 推荐:http://blog.csdn.net/inn ...
- 报错--"npm audit fix" or "npm audit"
如图: 根据提示输入 npm audit fix --force 如图: 根据提示输入: npm audit
- [原]Openstack之identity server(keystone)
本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 重新温习keystone的概念和理解 --------------------- ...
- ftp主动与被动模式详解
FTP是仅基于TCP的服务,不支持UDP.与众不同的是FTP使用2个端口,一个数据端口和一个命令端口(也可叫做控制端口).通常来说这两个端口是21(命令端口)和20(数据端口).但FTP工作方式的不同 ...
- testmath
$\Huge ans = \frac{ \sum\limits_{i=1}^{m}{ (x_i - \bar{x})^2 } }{m} \cdot m^2 \\$