Class Literal(Java)
前言
上一节我们讨论过通过关键字synchronized实现线程同步,同时最主要了解到在Java中className.class所代表的具体含义,在博客写完后,感觉还是有点迷糊,然后再次深入了解后,原来关于className.class在Java语言规范中定义为(Class Literal),我们翻译为类文字好像比较生硬,还是以英文作为说明最好,本节我们再来详细讨论下Class Literal。
Class Literal
在java语言规范中有对Class Literals的定义《https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.2》:它是由类,接口,数组或原始类型的名称或伪类型void组成的表达式,后面紧跟【.】和【class】。比如C.class,那么它的类型则为Class <C>,其中C是类,接口或数组类型的名称。比如p.class的类型(其中p是基本类型的名称)是Class <B>,其中B是装箱转换后的类型p的表达式的类型,也就说例如int.class,它的Class Literal实际上是Class<Integer>。而void.class,它的Class Literal是Class<Void>。最后对于类型的变量当然也就没有Class Literal。比如我们要想获取包装类Integer的Class Literal,可以通过如下两种方式来获取:
System.out.println(Class.forName("java.lang.Integer"));
System.out.println(Integer.class);
接下来我们通过定义一个类来更加深入了解,如下:
class Test {
}
我们再来通过上述方法获取其Class Literal,此时forName中参数则是类所在包空间,如下:
Class cls = Class.forName("com.company.Test");
System.out.println(cls.toString()); System.out.println(Test.class);
还记得上一节我们重点讲解的就是通过关键字synchronized,在其方法或同步块中的监视器或锁定对象是className.class即Class Literal,我们也知道在类加载时机的第一阶段中的第三件事情则是在JVM中生成对于对应类且只存在一次的java.lang.class的对象,该对象包含有关该类的元数据等等,也就是说该锁定对象就是对该类生成的java.lang.class对象的引用。例如,如下例子:
class Test {
public void lockMethod1() {
synchronized (Test.class) {
System.out.println("1");
}
} public void lockMethod2() {
synchronized (Test.class) {
System.out.println("2");
}
}
}
当发生并发分别执行如上方法一和方法二,若此时执行到方法二时,但是方法一并未执行完成,通过上述对锁定对象的详细分析,此时必将导致方法二会被阻塞,直到方法一执行完毕,释放线程同步锁。到此我们讲解了Class Literal在线程同步中的使用,其实在反射中使用的机会也比较多,比如创建命令行将程序进行重启的命令,我们通过ProcessImpl类中的createCommandLine方法,创建命令行,这里我们尝试使用反射来实现,C#中通过反射调用方法,其参数是Object数组(记得是这样),在java中通过反射调用方法,其参数就是ClassLiteral泛型数组,所以我们必须显式指定参数类型,这就应用到了Class Literal,如下:
public static void main(String[] args) throws
InvocationTargetException,
IllegalAccessException,
NoSuchMethodException,
ClassNotFoundException { final String[] cmd = {
"shutdown.exe",
"/r",
"/t 0",
}; final String executablePath = new File(cmd[0]).getPath(); final Class<?> impl = ClassLoader.getSystemClassLoader().loadClass("java.lang.ProcessImpl"); final Method myMethod = impl.getDeclaredMethod(
"createCommandLine",
new Class[] {
int.class,
String.class,
String[].class
});
myMethod.setAccessible(true); final Object result = myMethod.invoke(
null,
2,
executablePath,
cmd);
System.out.println(result); }
总结
本节我们再一次深入并了解className.class,在java语言规范中其专有名词为Class Literal,并对其在线程同步中的使用以及为何就保证了线程安全又进行了啰嗦式的分析,最后也通过一个反射例子作为Class Literal的使用练习而结束本文,至此关于Class Literal的学习算告一段落。下一节我们进入学习Hibernate。
Class Literal(Java)的更多相关文章
- 如何夯实(Java)编程基础,并深入学习和提高
如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...
- TCL校园招聘——软件开发工程师(java) 只招5个。。。
简介 TCL集团股份有限公司创立于1981年,是全球性规模经营的消费类电子企业集团之一,广州2010年亚运会合作伙伴,总部位于广东省惠州市仲恺高新区TCL科技大厦.旗下拥有TCL集团.TCL多媒体科技 ...
- UEditor上传图片到七牛云储存(java)
我们的网站一般放在虚拟空间或者服务器上,图片如果存在本地目录,会占用很多空间和流量,还增加了负担,好的办法是把图片存放到云储存服务里面,平时用url去拿 云储存:普遍说又拍云和七牛比较好,看到七牛免费 ...
- 开源工作流 Bonita BPM (JAVA)
Bonita BPM 开源工作流 Bonita BPM (JAVA) http://www.bonitasoft.com/
- ZeroMQ(java)中对IO的封装(StreamEngine)
哎,各种各样杂七杂八的事情...好久没有看代码了,其实要搞明白一个与IO相关的框架,最好的办法就是把它的I/0的读写两个过程搞清楚...例如在netty中,如果能将eventLoop的运行原理搞清楚, ...
- 编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码
转自:编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码 JDK:java version “1.8.0_31”Java(TM) SE Runtime Environment ( ...
- 随机产生30个两个两位数相加的题目(java)
编程思路: 1首先遇到JAVA产生随机数的问题. 2把产生的随机数设定范围. 3把划分的范围再分四个小区段分别对应四则运算法则加减乘除. 4打印输出. 题目源代码(Java) package coun ...
- Android(java)学习笔记267:Android线程池形态
1. 线程池简介 多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力. 假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...
- MongoDB的update有关问题(JAVA)——如何一次更新所有的相同记录
MongoDB的update问题(JAVA)——怎么一次更新所有的相同记录用如下这个函数:public WriteResult update(DBObject q, DBObject o, boo ...
随机推荐
- 安装mysql8.0.17指南
1.首先,下载社区版mysql(下载地址https://dev.mysql.com/downloads/mysql/) 2.下载之后,将文件解压到自己想要安装的目录(如,本人将解压文件放置g://my ...
- Centos7.6部署k8s v1.16.4高可用集群(主备模式)
一.部署环境 主机列表: 主机名 Centos版本 ip docker version flannel version Keepalived version 主机配置 备注 master01 7.6. ...
- python3默认参数陷阱
默认参数的值是容器类型,每次调用函数的时候,如果不传值,会用公用资源池 def func(k, v=[]): v.append(k) print(v) func('wt') func('ab', [] ...
- 10.方法重写Override
方法重写:Override: 需要有继承关系,子类重写父类的方法! 方法名必须相同 参数列表必须相同 修饰符:范围可以扩大,但不能缩小:public>protected>defalut&g ...
- 前端开发利器 Web Replay
前端开发人员收到测试发来的 bug 后,通常比较头疼复现的问题. 即使测试人员录了视频,照着一步步操作也不一定能复现,例如bug是与当时的数据相关的. 为了解决这个问题,Firefox 推出了一个重磅 ...
- 嵩天老师python网课爬虫实例1的问题和解决方法
一,AttributeError: 'NoneType' object has no attribute 'children', 网页'tbody'没有子类 很明显,报错的意思是说tbody下面没有c ...
- java.sql.Date与java.sql.Date区别
public static void main(String[] args) { java.sql.Date createTime = new java.sql.Date(System.current ...
- 爬虫之 cookie , 验证码,模拟登陆,线程
需求文档的定制 糗事百科的段子内容和作者(xpath的管道符)名称进行爬取,然后存储到mysql中or文本 http://sc.chinaz.com/jianli/free.html爬取简历模板 HT ...
- pycharm版本下载地址
https://www.runoob.com/w3cnote/pycharm-windows-install.html 下载社区版本,因为免费 其余按照默认安装即可
- JAVA byte数组转化为16进制字符串输出
最简单的方法: 利用javax.xml.bind包下的DatatypeConverter printHexBinary public static java.lang.String printHexB ...