前言

上一节我们讨论过通过关键字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. 实用代码|Linux定时检查应用状态

    有时候,我们挂在服务器上的应用会因为一些特殊情况挂掉,致使项目经理又对我们说:又挂了!赶紧去看看!于是又了以下脚本,使用shell编写,用于定时检查应用情况,挂掉则重启.这里以tomcat为例. 根据 ...

  2. c#移位运算符("<<"及">>")

    C#是用<<(左移) 和 >>(右移) 运算符是用来执行移位运算. 左移 (<<) 将第一个操作数向左移动第二个操作数指定的位数,空出的位置补0.  左移相当于乘. ...

  3. c#数字图像处理(五)全等级直方图灰度拉伸

    灰度拉伸也属于线性点运算的一种,也可以通过上一节的程序得到.但由于它在点运算的特殊性,所以把它单独列出来进行介绍. 灰度拉伸定义 如果一幅图像的灰度值分布在全等级灰度范围内,即在0~255之间,那么它 ...

  4. 【WPF学习】第二十七章 Application类的任务

    上一章介绍了有关WPF应用程序中使用Application对象的方式,接下来看一下如何使用Application对象来处理一些更普通的情况,接下俩介绍如何初始化界面.如何处理命名行参数.如何处理支付窗 ...

  5. Linux文件内容重定向

    文件描述符 可以理解为linux跟踪打开文件,而分配的一个数字,这个数字有点类似c语言操作文件时候的句柄,通过句柄就可以实现文件的读写操作. 用户可以自定义文件描述符范围是:3-num,这个最大数字, ...

  6. SpringBoot2.x整合JDBC及初始化data.sql和schema.sql脚本

    今天在使用SpringBoot2.x版本整合JDBC时遇到了一些问题:由于我之前一直用SpringBoot1.5的版本,所以直接在yml里按照1.5的版本配置了属性,没想到2.x直接不能用了.首先是数 ...

  7. Realm及相关对象(四)

    Shiro Realm 1.UserRealm 父类 AuthorizingRealm 将获取 Subject 相关信息分成两步:获取身份验证信息(doGetAuthenticationInfo)及授 ...

  8. C语言创建文件夹

    问题需求:在程序中需要使用文件夹时,一般可以先在程序目录或某一路径下创建一个文件夹,然后使用该文件夹. 这种方法比较麻烦,需提前创建文件夹. 使用C语言创建文件夹的代码可以如下: #include & ...

  9. 微信小程序框架分析小练手(一)——猫眼电影底部标签导航制作

    旧版猫眼电影底部有4个标签导航:电影.影院.发现.我的,如下图所示: 一.首先,打开微信开发者工具,新建一个项目:movie.如下图: 二.建立如下的一些目录: 三.将底部标签导航图标的素材放到ima ...

  10. 遍历CSDN博客

    --http://blog.csdn.net/leixiaohua1020/article/list/14?viewmode=contents function saveData(data) loca ...