Java 7 –反编译项目硬币

大家好,该是从2012年开始写作的时候了。正如您在其他博客中可能已经看到的那样,有一些更改可以使您使用Java编程时的开发人员生活变得更加轻松:Diamond运算符,Switchs中的Strings,尝试使用资源,多次捕获等

在本文(PART I)中,我们将看到Java 7 Project Coin(JSR 334)中提出的一些小改动,然后(在第二部分中)我们将对它们进行反编译,以查看编译器在做什么(对于仅用于教育目的)。

你需要什么

  • NetBeans 7+或任何其他支持Java 7的IDE
  • JSDK 7+
  • JAD反编译 [R 或 Java的反编译

钻石算子

泛型帮助我们减少了ClassCastExceptions,但是有时它会使代码难以阅读。 钻石算子是一个非常不错的变化。 成像您需要按城市对客户进行分组。 您将需要以下内容:

//suppose the classes City and Customer exist
...
Map<City,List<Customer>> map = new
HashMap<City,List<Customer>>();
...

现在,如果您还需要按国家/地区对数据进行分组怎么办:

//suppose the classes Country, City and Customer exist
...
Map<Country,MapltCity,List<Customer>>> map = new HashMapl&t;Country,MapltCity,ListltCustomer>>>();
...

现在,它开始变得很难阅读,对吧? 如果您还需要按地区分组怎么办?

//suppose the classes Region, Country, City and Customer exist
...
Map<Region,Map<Country,Map<City,List<Customer>>>> map = new HashMap<Region, Map<Country,Map<City,List<Customer>>>>();
...

所以你怎么看? 读取这样的代码根本不容易。 幸运的是,新的Diamond运算符对代码的可读性有很大帮助。 最后的代码可以在Java 7中重新编码,如下所示:

//suppose the classes Region, Country, City and Customer exist
...
Map<Region,Map<Country,Map<City,List<Customer>>>> map = new HashMap<>();
...

好了很多!

开关中的弦

我已经等了很多!!! 我记得我刚开始Java时代的日子,我确实需要在switch中使用Strings。 好吧,我的等待终于结束了。 在Java的早期版本中,您必须编写如下代码:

//in a class
...
public void stringToNumber(String str)
{if(str.equalsIgnoreCase("one")){System.out.println(1);}else if(str.equalsIgnoreCase("two")){System.out.println(2);}else if(str.equalsIgnoreCase("three")){System.out.println(3);}
}
...

在Java 7中,您可以这样编写:

//in a class
...
public void stringToNumber(String str)
{switch(str){case "one":System.out.println(1);break;case "two":   System.out.println(2);break;   case "three":System.out.println(3);break;}
}
...

甚至NetBeans也可以选择自动转换:

尝试使用资源和多重捕获

在此版本中,这是一个很好的增强,现在您不必担心关闭那些ResultSet,States,FileInputStreams等。 您只需要使用新的try结构,编译器就会为您服务。 您甚至可以通过新的try结构将自己的类创建为Closeable(这是一个新接口)。 以下是通过流进行的经典文件访问:

//in a class
import java.io.*;
...
public static void copyFile(String path) throws IOException, NullPointerException 
{File file = new File(path);FileOutputStream fout = null;FileInputStream fin = null;try {try {fout = new FileOutputStream("file.dat");fin = new FileInputStream(file);byte[] bytes = new byte[1024];int leido = 0;while ((leido = fin.read(bytes)) != -1) {fout.write(bytes, 0, leido);}} finally {if (fout != null) {fout.close();}if (fin != null) {fin.close();}}} catch (NullPointerException ex) {ex.printStackTrace();throw ex;}catch (IOException ex) {ex.printStackTrace();throw ex;}}
...

如果您注意到了,为了确保打开的流一旦完成就被关闭,则必须编写一个try / finally块并自己关闭它们。 在Java 7中,可以使用新的try结构和新的NIO.2类以更好的方式和更少的代码行实现相同的行为:

//in a class
import java.nio.file.*;
import java.io.*;
...
public static void copyFile(String src) throws IOException, NullPointerException 
{Path path = FileSystems.getDefault().getPath(src);try (FileOutputStream fout = new FileOutputStream("file.dat")) {Files.copy(path, fout);} catch (NullPointerException | IOException ex) {ex.printStackTrace();throw ex;}
}
...

二进制文字和下划线

现在,您可以将整数表示为二进制文字,这在编程低级API时非常理想,也可以使用下划线以使您的值更易读:

//in a class
...
public static void coin() 
{int binaryNum = 0b10; //This is number 2 in binary codedouble value1 = 1000000000; //hard to read?double value2 = 1_000_000_000; //Easy to read with Java 7double value3 = 0b101010110111; //hard to read?double value4 = 0b1010_1011_0111; //Easy to read with Java 7double pi = 3.14_15_92; //another example of readability
}
...

因此,更少的代码,更高的生产率和更好的代码可读性是Project Coin的宗旨! (在这里没有看到的其他东西)。

钻石算子

这是我们在上一篇文章中刚刚看到的钻石操作员示例:

//suppose the classes Region, Country, City and Customer exist
import java.util.*;
...
Map<region,map<country,map<city,list>>> map = new HashMap<>();
...</region,map<country,map<city,list

现在,让我们看看编译器生成的代码是什么样的:

import java.util.*;
...
java.util.Map map = new HashMap();
...

只是一个老派的地图定义和实例化...为什么? 因为这就是泛型的工作方式:

When you take an element out of a Collection, you must cast it to the type of element that is stored in the collection. Besides being inconvenient, this is unsafe. The compiler does not check that your cast is the same as the collection's type, so the cast can fail at run time.Generics provides a way for you to communicate the type of a collection to the compiler, so that it can be checked. Once the compiler knows the element type of the collection, the compiler can check that you have used the collection consistently and can insert the correct casts on values being taken out of the collection.

这意味着编译器将在编译时检查您是否使用了正确的类,并将向生成的类添加任何必需的强制转换。 例如:

//suppose the classes Region, Country, City and Customer exist
import java.util.*;
...
Map<region,map<country,map<city,list>>> map = new HashMap<>();
Map<country,map<city,list>> m = map.get(new Region());
...
</country,map<city,list</region,map<country,map<city,list

您将获得如下内容:

//suppose the class Region exists
import java.util.*;
...
Map map = new HashMap();
Map m = (Map)map.get(new Region()); //the compiler added the cast
...

开关中的弦

记住上一篇文章中介绍的Strings in switch示例:

//in a class
...
public void stringToNumber(String str)
{switch(str){case "one":System.out.println(1);break;case "two":   System.out.println(2);break;   case "three":System.out.println(3);break;}
}
...

反编译之后,您会注意到开关状态菜单现在如何支持字符串:

//in a class
...
public static void stringInSwitch(String str)
{String s = str;byte byte0 = -1;switch(s.hashCode()){case 110182: if(s.equals("one"))byte0 = 0;break;case 115276: if(s.equals("two"))byte0 = 1;break;case 110339486: if(s.equals("three"))byte0 = 2;break;}switch(byte0){case 0: // ''System.out.println(1);break;case 1: // '01'System.out.println(2);break;case 2: // '02'System.out.println(3);break;}
}
...

是的……这是一个小技巧。 并不是直接在switch语句中支持字符串,而是它们的hashCodes是(hashCodes是整数)。 通过查看代码,我意识到最好不要在switch语句中使用Strings,因为最后,您将获得两个switch语句……

尝试使用资源和多重捕获

记住上一篇文章中的尝试资源和多捕获示例:

//in a class
import java.nio.file.*;
import java.io.*;
...
public static void copyFile(String src) throws IOException, NullPointerException 
{Path path = FileSystems.getDefault().getPath(src);try (FileOutputStream fout = new FileOutputStream("file.dat")) {Files.copy(path, fout);} catch (NullPointerException | IOException ex) {ex.printStackTrace();throw ex;}
}
...

本示例在一个示例中使用try资源,并进行多捕获。 当我尝试使用JAD Java Decompiler对生成的类进行反编译时,我对嵌套的try语句有很多误解,因此我决定尝试JD Java Decompiler,结果如下:

//in a class
import java.nio.file.*;
import java.io.*;
...
public static void copyFile(String src) throws IOException, NullPointerException
{Path path = FileSystems.getDefault().getPath(src, new String[0]);try {FileOutputStream fout = new FileOutputStream("file.dat"); Throwable localThrowable2 = null;try { Files.copy(path, fout);}catch (Throwable localThrowable1){localThrowable2 = localThrowable1; throw localThrowable1;} finally {if (fout != null) { //I added this { symbol for readabilityif (localThrowable2 != null) { //I added this { symbol for readabilitytry { fout.close(); } catch (Throwable x2) { localThrowable2.addSuppressed(x2); } } //I added this } symbol for readabilityelse { //I added this { symbol for readabilityfout.close();  } //I added this } symbol for readability} //I added this } symbol for readability}} catch (IOException ex) {ex.printStackTrace();throw ex;}
}
...

从最后的代码中,我们可以看到编译器如何使用新的(JDK 7) + addSuppressed(Throwable):void类Throwable来确保复制过程中抛出的任何异常不会丢失。 这很重要,因为在应用程序中查找错误时,您将需要所有可能的异常。 另外,请注意,所有关闭操作都是在finally语句中完成的,以确保在过程结束时始终关闭资源。

二进制文字和下划线

我认为您可以弄清楚对最后一个功能进行反编译后会得到什么……

//in a class
...
public static void coin() 
{int binaryNum = 0b10; //This is number 2 in binary codedouble value = 1000000000; //hard to read?double value = 1_000_000_000; //Easy to read with Java 7double value = 0b101010110111; //hard to read?double value = 0b1010_1011_0111; //Easy to read with Java 7double pi = 3.14_15_92; //another example of readability
}
...

是的,没有什么新东西了……编译器只重写没有下划线的值,并将二进制值转换为整数值:

//in a class
...
public static void coin(
{int binaryNum = 2;double value1 = 1000000000D;double value2 = 1000000000D;double value3 = 2743D;double value4 = 2743D;double pi = 3.1415920000000002D;
}
...

好的,仅此而已。 希望大家都喜欢Java 7中的Project Coin(JSR334)的新功能。Java8中的Project Coin II还有更多改进,我们将在以后的文章中进行检查。 再见!

参考:我们的JCG合作伙伴提供的 Java –项目硬币反编译和Java 7 –项目硬币反编译第二部分 Java和ME博客上的Alexis Lopez。


翻译自: https://www.javacodegeeks.com/2012/04/java-7-project-coin-decompiled.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373335.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Excel表里面插入背景图

工作中我们会经常用到MS Excel&#xff0c;通常我们打开MS Excel&#xff0c;里面的工作表都是空白单调的背景。当然了&#xff0c;MS Excel可以在工作簿里面插入背景图片。那么问题来了&#xff0c;如果你没有安装Microsoft Office&#xff0c;该如何在Excel文件里面插入好看的…

实现两级下拉框的联动

1.实现两级下拉框的联动。 功能&#xff1a;实现点击年级下拉框&#xff0c;加载对应科目的下拉框。 第一步&#xff1a;首先要加载年级下拉框中的数据。 01.在GradeDAL层&#xff08;数据访问层&#xff09;写一个方法&#xff0c;查询所有年级的信息。 /// <summary>//…

python连接SQL Server取多个结果集:Pymssql模块

基本的用法可以参考&#xff1a;python连接SQL Server&#xff1a;Pymssql模块 和上一篇文章中的代码&#xff0c;只取一个结果集不同&#xff0c;这次会一次运行2个sql语句&#xff0c;然后分别取出2个结果集&#xff0c;打印输出。 代码中有详细的注释&#xff0c;一看就明白…

Xen安全架构sHype/ACM策略配置图文教程

实验要求 1. 熟悉Xen虚拟化平台部署&#xff1b; 2. Xen sHype/ACM安全架构中的Simple TE和Chinese Wall策略及事实上现机制的分析与验证。 第1章 Xen环境部署 1.1 版本号选择 因为Ubuntu使用广泛。软件包易于下载。我们选择Ubuntu系统进行Xen部署…

java弹出虚拟键盘_JS实现电脑虚拟键盘的操作

本文实例为大家分享了JS实现电脑虚拟键盘的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下需求&#xff1a;1.当输入框光标聚焦时&#xff0c;电脑虚拟键盘弹出2.在输入框输入内容时&#xff0c;键盘跟着变化具体实现代码如下&#xff1a;Html部分&#xff1a;电脑键…

JBoss Drools –入门

这篇文章是关于我如何掌握JBoss Drools的 。 其背后的原因是&#xff1a;SAP收购了我公司当前的规则引擎&#xff0c;而Drools是我们将寻找的另一种选择&#xff0c;只要有人掌握了概念验证的技能即可。 尽管似乎有大量的文档&#xff0c;但是我总是会通过示例来发现它是有帮助…

android使用bintray发布aar到jcenter

前言 这两天心血来潮突然想把自己的android library的aar放到jcenter里面&#xff0c;这样一来自己便可以在任何时间任何地点通过internet得到自己的library的引用了&#xff0c;况且现在android studio已经默认使用jcenter的repositories作为依赖来源&#xff0c;以前的mavenc…

PHP 进程详解

PHP 进程详解PHP 进程详解 如下内容从《操作系统精髓与设计原理》中总结提炼得出&#xff0c;删除了大部分对于理解进程有干扰的文字&#xff0c;对进程知识结构进行的梳理。几乎所有内容为按照书本上摘抄下来的&#xff0c;我目前还总结提炼不出像作者这么深刻的见解。那么就先…

java都要caps标点_第 1 章 管理 Java CAPS 用户

第 1 章 管理 Java CAPS 用户在此处列出的主题提供了有关如何管理 Sun JavaTM Composite Application Platform Suite (Java CAPS) 中的用户的信息。如果您有任何问题&#xff0c;请参见 http://goldstar.stc.com/ 中的 Java CAPS Web 站点。管理系统信息库用户此类别包含以下用…

基于OpenCV 的美颜相机推送直播流

程序流程&#xff1a; 1.图像采集 先从opencv&#xff08;2.4.10版本&#xff09;采集回来摄像头的图像&#xff0c;是一帧一帧的 每一帧图像是一个矩阵&#xff0c;opencv中的mat 数据结构。 2.人脸的美化 人脸美化&#xff0c;我们用的皮肤检测&#xff0c;皮肤在颜色空间是特…

Spring线程池服务

线程池对于执行同步和异步过程非常重要。 本文介绍如何使用Spring开发和监视线程池服务。 创建线程池已通过两种替代方法进行了说明。 二手技术 &#xff1a; JDK 1.6.0_21 Spring3.0.5 Maven的3.0.2 步骤1&#xff1a;建立已完成的专案 创建一个Maven项目&#xff0c;如下…

我的世界java村民繁殖_我的世界:Java19w08a更新,村民加强守卫,小狐狸背叛

虽然这句话很绕口&#xff0c;其实意思很简单&#xff0c;那就是之前的隐身药水没有什么用&#xff0c;该被打还是被打。因为这个可是害惨了流浪商人&#xff0c;不过这次好了&#xff0c;流浪商人在喝了隐身药水之后就能安全度过晚上了。NO.3 皮革马铠马铠是属于马的盔甲&…

欧莱雅眉笔banner个人设计

眉笔名称&#xff1a;眉笔大师三头塑形眉笔 &#xff0c;之所以没用吧这个商品名称放大&#xff0c;是我觉得它是一个名称&#xff0c;而我把自己想的广告词“出彩只需一笔” 放大不仅能凸显出这只笔的强大&#xff0c;还表示了一种有了我这支眉笔你会更出彩更漂亮&#xff0c…

使用带有注释和JQuery的Spring MVC 3的Ajax

与Ajax一起工作对我来说一直很有趣&#xff01; 是不是 &#xff1f; 我将使您轻松将Ajax与Spring MVC 3和JQuery结合使用。 这篇文章将向您说明如何在工业编码的现实生活中使用Ajax。 和往常一样&#xff0c;我们将在Spring MVC 3框架中以Ajax的实际示例为例&#xff0c;并将其…

java百度云文件上传_关于如何在自己项目集成百度云BCE文件上传STS方案

1、 项目背景由于本人项目需要&#xff0c;需要在视频点播服务之中需要加载字幕文件(通用格式srt)&#xff0c;经过比较好几家的公有云服务&#xff0c;最后选择只有百度云提供字幕服务。字幕&#xff1a;我们通常在观看外语电影的是&#xff0c;没有国语版时候只能通过下载字幕…

hdu 3507 Print Article(斜率优化DP)

题目链接&#xff1a;hdu 3507 Print Article 题意&#xff1a; 每个字有一个值&#xff0c;现在让你分成k段打印&#xff0c;每段打印需要消耗的值用那个公式计算&#xff0c;现在让你求最小值 题解&#xff1a; 设dp[i]表示前i个字符需要消耗的最小值&#xff0c;那么有dp[i]…

第三章 consul服务注册与服务查询

1、定义一个服务 https://www.consul.io/docs/agent/services.html 该方法是服务注册中提供服务的最常用的方法。 关于服务的定义&#xff1a;服务的属性我们会在后边每出现一个总结一个&#xff0c;最后再做总结。 2、服务注册 2.1、创建服务文件所存放的文件夹 说明&#xff…

coreos 安装mysql_CoreOS 在 PC 上快速安装方法指南

意义能够以最快的速度安装部署Linux操作系统。安装快速简单&#xff0c;几乎不花时间就可以开始运行Docker。运行速度非常快。使用内存硬盘。我的情况win8 笔记本偶尔玩游戏&#xff0c;但是装Linux双系统可能需要我一天的时间来完成。我的所有业务都只需要在Docker中跑就可以了…

Session 的配置和特性

session的配置 对于session的配置是php.ini中配置 session数据都是保存在文本文件中 设置session文件的保存位置 说明&#xff1a; 默认是保存在windows/temp目录 设置session保存作为客户端标识的数据使用cookie 设置session保存客户端标识的数据&#xff0c;只使用cookie 说明…

OAuth与Spring Security

摘自Wikipedia&#xff1a; OAuth &#xff08; 开放式身份验证 &#xff09;是一种开放式身份验证标准。 它允许用户与其他站点共享存储在一个站点上的私有资源&#xff08;例如照片&#xff0c;视频&#xff0c;联系人列表&#xff09;&#xff0c;而不必发出其凭据&#xff…