大家好,该是从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

Java 7 –反编译项目硬币相关推荐

  1. java 反编译项目_Java 7 –反编译项目硬币

    java 反编译项目 大家好,该是从2012年开始写作的时候了.正如您在其他博客中可能已经看到的那样,有一些更改可以使您使用Java编程时的开发人员生活变得更加轻松:Diamond运算符,Switch ...

  2. 【项目实战】Java代码反编译工具的使用 以及 如何对Java代码进行混淆?

    一.背景 现在交付给客户的代码,虽然不是以源码的形式交付,但是还经常会需要进行反编译,如何更好的做到反编译呢?本文探讨的是如何进行反编译的方法. 二. Java代码反编译工具的使用 (1)使用jad ...

  3. 如何在Eclipse 3.3上安装jadclipse[java的反编译工具] 收藏

    如何在Eclipse 3.3上安装jadclipse[java的反编译工具] 收藏 jad是java的反编译工具,是命令行执行,反编译出来的源文件可读性较高.可惜用起来不太方便.还好 找到eclips ...

  4. Java的反编译工具提供官网下载

    今天我们要来分享一些关于Java的反编译工具,反编译听起来是一个非常高上大的技术词汇,通俗的说,反编译是一个对目标可执行程序进行逆向分析,从而得到原始代码的过程.尤其是像.NET.Java这样的运行在 ...

  5. java如何编译和反编译,JAVA 如何反编译的自己的程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 JAVA 如何反编译的自己的程序 反编译的工具有好多, 在众多的JAVA反编译工具中,有几种非常著名的工具使用了相同的核心引擎--JAD,其中主要包括:F ...

  6. 关于java的反编译的一些坑,反编译后代码中的$+数字是什么

    本人菜鸡一名,说的不够周到还请见谅.现在拿到一份虚机环境然后想把环境中的war还原成代码,反编译嘛,我觉得大部分人都接触过,看看源码啊啥的.先简单说说本次我用到的反编译工具. 首先说推荐的好用的工具J ...

  7. java jar反编译后保存_java根据jar包反编译后修改再打包回jar的做法

    1. 得到一个待要修改的jar包 2. 我的环境是windows,然后解压这个jar包,得到一堆class文件,这时候就找到你需要的那个class文件 3. 我首先是使用jd-gui工具看一下这个cl ...

  8. java eclipse 反编译_java的class文件反编译和Eclipse、MyEclipse反编译插件安装、使用...

    本帖最后由 pig2 于 2014-3-4 10:58 编辑 前言 我们在做项目中,可能经常需要看下别人写的源码,而别人提供的往往是jar文件,根本看不了,很影响开发效率.本人最近就为此而感到很不爽, ...

  9. Java防止反编译实践

    文章目录 概述 资源准备 环境准备(简单操作可跳过) 改造编译插件 改造Tomcat源码 改造Spring源码 环境测试 概述  本文主要是介绍如何通过改造Maven-war-plugin插件,Spr ...

最新文章

  1. Wiz开发 定时器的使用与处理
  2. 关于一个Panel上鼠标不及时响应MouseLeave事件
  3. 偷梁换柱做自己的封装系统
  4. ffplay分析 (seek操作处理)
  5. windows中使用scrapyd遇到的问题
  6. Win2008 R2 VDI动手实验系列之一:Active Directory搭建
  7. 计算机网络——访问网站数据传输过程
  8. Java进行spark计算
  9. 如何解决忙死领导,闲死下属的问题?
  10. 深度学习 —— 使用 gensim 实现 word2vec
  11. Python函数参数的值传递机制
  12. 跟据URL来实现WebService
  13. 无恶意的协议才有效力
  14. 标准库:urllib/urllib2
  15. 数论二·Eular质数筛法
  16. 软件质量与测试--第四周作业 wcPro
  17. C语言习题:猜数字游戏(C语言随机数)
  18. 成为测试大牛——测试领域的变与不变
  19. 实验:GNS3中创建PC机与连接交换机实现互联互通
  20. JVM性能调优(4)——性能调优工具

热门文章

  1. aws terraform_在AWS第1部分中使用Terraform自动缩放组:基本步骤
  2. graphql 有必要吗_您准备好观看GraphQL了吗?
  3. kie-api_7.0上的新KIE持久性API
  4. hibernate语句_如何优化Hibernate EllementCollection语句
  5. u3d ab包 循环依赖_为什么要保持软件包依赖项自由循环的五个原因
  6. 摇滚bono_Java比以往任何时候都摇滚
  7. Java 11快多少?
  8. 使用Spring Data R2DBC进行异步RDBMS访问
  9. 用Jackson编写大型JSON文件
  10. cassandra使用心得_使用Cassandra和Nutch爬网