前言

上一节我们讨论过通过关键字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)的更多相关文章

  1. 如何夯实(Java)编程基础,并深入学习和提高

    如何夯实(Java)编程基础,并深入学习和提高? 240赞同反对,不会显示你的姓名 匿名用户 240 人赞同 多学习...网上自学的学习网站很多,见以下榜单~一.汇总榜单: 公开课_学习网站导航 收录 ...

  2. TCL校园招聘——软件开发工程师(java) 只招5个。。。

    简介 TCL集团股份有限公司创立于1981年,是全球性规模经营的消费类电子企业集团之一,广州2010年亚运会合作伙伴,总部位于广东省惠州市仲恺高新区TCL科技大厦.旗下拥有TCL集团.TCL多媒体科技 ...

  3. UEditor上传图片到七牛云储存(java)

    我们的网站一般放在虚拟空间或者服务器上,图片如果存在本地目录,会占用很多空间和流量,还增加了负担,好的办法是把图片存放到云储存服务里面,平时用url去拿 云储存:普遍说又拍云和七牛比较好,看到七牛免费 ...

  4. 开源工作流 Bonita BPM (JAVA)

    Bonita BPM 开源工作流 Bonita BPM  (JAVA) http://www.bonitasoft.com/

  5. ZeroMQ(java)中对IO的封装(StreamEngine)

    哎,各种各样杂七杂八的事情...好久没有看代码了,其实要搞明白一个与IO相关的框架,最好的办法就是把它的I/0的读写两个过程搞清楚...例如在netty中,如果能将eventLoop的运行原理搞清楚, ...

  6. 编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码

    转自:编译哈工大语言技术平台云LTP(C++)源码及LTP4J(Java)源码 JDK:java version “1.8.0_31”Java(TM) SE Runtime Environment ( ...

  7. 随机产生30个两个两位数相加的题目(java)

    编程思路: 1首先遇到JAVA产生随机数的问题. 2把产生的随机数设定范围. 3把划分的范围再分四个小区段分别对应四则运算法则加减乘除. 4打印输出. 题目源代码(Java) package coun ...

  8. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  9. MongoDB的update有关问题(JAVA)——如何一次更新所有的相同记录

    MongoDB的update问题(JAVA)——怎么一次更新所有的相同记录用如下这个函数:public WriteResult update(DBObject q,  DBObject o,  boo ...

随机推荐

  1. 匈牙利算法(Kuhn-Munkres)算法

    这个算法有点难度,一般比较标准的描述网页上也有相关的描述,我在这里就简单的用十分通俗的语言给大家入个门 主要可以结合https://blog.csdn.net/zsfcg/article/detail ...

  2. [计算几何+图论]doge

    题意 在平面直角坐标系上,你有一只doge在原点处.doge被绳子拴住了,绳子不会打结,没有弹性(但很柔软),并且长度为L.平面上有一些目标,因此你的doge会按照顺序去捡起它们,但是doge只能走直 ...

  3. [ZJOI2008]树的统计(树链剖分)

    [ZJOI2008]树的统计(luogu) Description 一棵树上有 n 个节点,编号分别为 1 到 n,每个节点都有一个权值 w.我们将以下面的形式来要求你对这棵树完成一些操作: I. C ...

  4. 使用dlib基于CNN(卷积神经网络)的人脸检测器来检测人脸

    基于机器学习CNN方法来检测人脸比之前介绍的效率要慢很多 需要先下载一个训练好的模型数据: 地址点击下载 // dlib_cnn_facedetect.cpp: 定义控制台应用程序的入口点. // # ...

  5. linux下redis的部署

    https://www.cnblogs.com/wangchunniu1314/p/6339416.html https://www.linuxidc.com/Linux/2017-09/146894 ...

  6. 自定义BeanDefinitionRegistryPostProcessor

    自定义BeanDefinitionRegistryPostProcessor 概述 BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProce ...

  7. 用 C# 写一个 Redis 数据同步小工具

    用 C# 写一个 Redis 数据同步小工具 Intro 为了实现 redis 的数据迁移而写的一个小工具,将一个实例中的 redis 数据同步到另外一个实例中.(原本打算找一个已有的工具去做,找了一 ...

  8. layui+springmvc实现文件异步上传

    一.单文件上传 前端代码 <div class="layui-upload"> <div class="layui-upload-list"& ...

  9. ros中launch启动文件的使用方法

    launch文件:通过XML文件实现多节点的配置和启动(可自动启动ROS Master) launch文件中包含很多标签和属性 *launch文件语法 <launch> <node ...

  10. mplayer命令行模式下的使用方法【转】

    mplayer命令行模式下的使用方法http://hi.baidu.com/lovehack2006/blog/item/162ef9778214111eb051b9d4.htmlMPlayerMPl ...