前言

上一节我们讨论过通过关键字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. 【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发

    <ASP.NET Core 微服务实战>译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-tr ...

  2. BigInteger的权限设计

    通过储存菜单权限的一个字段(id自定义也是可以的) 1 将选中菜单树的id转换成字符数组的形式, 进行BigInteger对权限进行2的权的和计算 public static BigInteger s ...

  3. KMP——强大的next数组

    \(KMP\) 的原理不在这里仔细讲了,主要说说最近刷题总结出的 \(next\) 数组的强大功能. 部分例题来自<信息学奥赛一本通>的配套练习. 基于定义--字符串相同前后缀 " ...

  4. (ES6)JavaScript中面向对象类的实现

    在ES5中,我们就知道JS是不支持面向对象的,所以用函数模拟了一个构造函数来实现类的.那么在ES6中,在ES5的原理基础上,将代码书写更为简单,明了. 一.怎样用ES6创建类?首先看一看例子: cla ...

  5. php--->使用callable强制指定回调类型

    php 使用callable强制指定回调类型 如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function dosth($callback){ call_user_fu ...

  6. 科普文,搭建python开发环境

    Python简介!首先,是一门面向对象的程序设计语言,先说3个优点!1.有条理,简单,易学,易用.2.强大!可以把其他编程语言制作的模块利用起来.3.拥有丰富的库.Python作为高级编程语言,拥有的 ...

  7. oracle问题之SYSTEM表空间不足 (二)

    杂症二.SYSTEM表空间不足报错 一.杂症: PLSQL登录,报错: ORA-00604: 递归 SQL 层  出现错误 ORA-01653: 表.无法通过(在表空间中)扩展 ORA-02002: ...

  8. Capslock+程序介绍

    一直为编程时方向键不在盲打区域苦恼,今天接触了一个非常好的软件Capslock+. 软件特别小,一共只有九百多K,甚至不能称为软件,只能算一个很小的脚本了.但解决了我非常大的一个难题.安装好软件后可以 ...

  9. python实现ip地址的包含关系判断

    python的IPy模块虽然可以实现一些ip地址的判断,但是不是很完美,有些场景根本判断不出来,还会抛出异常,比如一个地址范围和一个ip/掩码,这种不同类型就无法判断. 对此通过自己写函数来实现ip地 ...

  10. win10下安装Anaconda3

    1.官方下载:https://www.anaconda.com/distribution/#download-section  (最新版直接下即可) 或者国内镜像下载:https://mirrors. ...