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.pswp.cn/news/373335.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373335.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373335.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

git安裝后找不見版本_無法安裝最新版本的Gitlab

這個問題不是代碼,而是Gitlab的安裝.我現在試圖安裝Gitlab幾天沒有成功.實際上,很久以前,他們提出了使用wget的方法非常好,但由于我們必須使用Curl的方法,所以不可能比下載更進一步.在Ubuntu 14.04機器上,以下命令有效&#xff1a;curl https://packages.gitlab.com/install/re…

在Excel表里面插入背景圖

工作中我們會經常用到MS Excel&#xff0c;通常我們打開MS Excel&#xff0c;里面的工作表都是空白單調的背景。當然了&#xff0c;MS Excel可以在工作簿里面插入背景圖片。那么問題來了&#xff0c;如果你沒有安裝Microsoft Office&#xff0c;該如何在Excel文件里面插入好看的…

Java 7:復制和移動文件和目錄

這篇文章是我關于Java 7 java.nio.file軟件包的系列文章的繼續&#xff0c;這次涵蓋了文件的復制和移動以及完整的目錄樹。 如果您曾經對Java缺少copy和move方法感到沮喪&#xff0c;那么請繼續閱讀&#xff0c;以免麻煩。 涵蓋范圍中包括非常有用的Files.walkFileTree方法。 但…

java 五子棋項目_Java項目如何實現五子棋小游戲

Java項目如何實現五子棋小游戲發布時間&#xff1a;2020-07-21 14:53:06來源&#xff1a;億速云閱讀&#xff1a;77作者&#xff1a;小豬小編這次要給大家分享的是Java項目如何實現五子棋小游戲&#xff0c;文章內容豐富&#xff0c;感興趣的小伙伴可以來了解一下&#xff0c;希…

Java中多線程的使用!!

簡介&#xff1a; 1.要了解多線程&#xff0c;首先我們得先了解進程和線程。那么什么是進程&#xff1f;進程就是一個正在運行的程序分配內存讓應用程序能夠運行的叫做進程。那么什么又是線程呢&#xff1f;線程&#xff1a;在一個程序中&#xff0c;負責代碼的執行&#xff0c…

java pkcs1轉pkcs8_pkcs1與pkcs8格式RSA私鑰互相轉換

1、PKCS1私鑰生成openssl genrsa -out private.key 1024private.key文件內容如下&#xff1a;-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDREk3uy4x9i4a16OYOYEp5Ir2f16lsmUHB2HjGDlxkU0ju9YApyeZlUXb191ZkxJ2vx2vKppN4gKLDy5r7JMTpwch1CNvceySX6DiM4lwTAnUEZiBYgNBNrKINEt…

嵌入式碼頭,Vaadin和焊接

當我開發Web應用程序時&#xff0c;我希望能夠從Eclipse快速啟動它們&#xff0c;而不必依賴各種重量級的tomcat或glassfish插件。 因此&#xff0c;我通常要做的只是創建一個可以直接從Eclipse運行的基于Java的簡單啟動器。 該啟動器會在幾秒鐘內啟動&#xff0c;因此使開發工…

創建真機調試證書(蘋果開發者平臺各個選項對應的含義)

創建真機調試證書&#xff08;蘋果開發者平臺各個選項對應的含義&#xff09; 原文地址&#xff1a;http://jingyan.baidu.com/article/ff411625b8141312e48237a7.html轉載于:https://www.cnblogs.com/siasyl/p/5340593.html

gl.vertexAtteib3f P42 講數據傳給location參數指定的attribute變量

參數  location  指定將要修改的attribute變量存儲位置 v0  指定填充attribute變量第一個分量的值 v1  指定填充attribute變量第二個分量的值 v2  指定填充attribute變量第三個分量的值 var VSHADER_SOURCE attribute vec4 a_Position;\n void main(){\n gl_Posit…

將Spring集成到舊版應用程序中

所有Spring開發人員喜歡做的事情之一就是將Spring塞入他們正在工作的任何應用程序中–這是我生活中的罪惡感之一&#xff1a;您看到一些代碼&#xff0c;認為它是垃圾&#xff0c;因為它包含幾個眾所周知的反模式&#xff0c;然后想想如果這個應用程序是Spring應用程序會多么酷…

java自己實現ioc_springioc原理、springmvc項目分析、自己實現IOC

從一個面試題開始&#xff1a;你自己實現IOC容器的話&#xff0c;保存bean你會使用什么數據結構來保存呢&#xff1f;現在的很多開發人員(甚至3年以上的)不一定能回答這問題&#xff0c;為什么會這樣呢&#xff1f;這個跟現在springboot現在已經高度成熟了&#xff0c;很多配置…

實現兩級下拉框的聯動

1.實現兩級下拉框的聯動。 功能&#xff1a;實現點擊年級下拉框&#xff0c;加載對應科目的下拉框。 第一步&#xff1a;首先要加載年級下拉框中的數據。 01.在GradeDAL層&#xff08;數據訪問層&#xff09;寫一個方法&#xff0c;查詢所有年級的信息。 /// <summary>//…

System.nanoTime()背后是什么?

在Java世界中&#xff0c;對System.nanoTime&#xff08;&#xff09;的理解非常好。 總有一些人說它是快速&#xff0c;可靠的&#xff0c;并且在可能的情況下&#xff0c;應該使用它代替System.currentTimemillis&#xff08;&#xff09;進行計時。 總的來說&#xff0c;他絕…

python連接SQL Server取多個結果集:Pymssql模塊

基本的用法可以參考&#xff1a;python連接SQL Server&#xff1a;Pymssql模塊 和上一篇文章中的代碼&#xff0c;只取一個結果集不同&#xff0c;這次會一次運行2個sql語句&#xff0c;然后分別取出2個結果集&#xff0c;打印輸出。 代碼中有詳細的注釋&#xff0c;一看就明白…

狀態不屬于代碼

Web應用程序中的“狀態”是什么&#xff1f; 它就是要存儲的數據&#xff08;無論目的地是什么—內存&#xff0c;數據庫&#xff0c;文件系統&#xff09;。 應用程序本身不得在代碼中存儲任何狀態。 這意味著您的類應僅包含帶有無狀態對象的字段。 換句話說&#xff0c;在程序…

Xen安全架構sHype/ACM策略配置圖文教程

實驗要求 1. 熟悉Xen虛擬化平臺部署&#xff1b; 2. Xen sHype/ACM安全架構中的Simple TE和Chinese Wall策略及事實上現機制的分析與驗證。 第1章 Xen環境部署 1.1 版本號選擇 因為Ubuntu使用廣泛。軟件包易于下載。我們選擇Ubuntu系統進行Xen部署…

Python 辨異 —— __init__ 與 __new__

__init__ 更多的作用是初始化屬性&#xff0c;__new__ 進行的是創建對象&#xff0c;顯然 __new__ 要早于 __init__ 發生。 考慮一個繼承自 tuple 的類&#xff0c;顯然在 __init__ 無法對其成員進行修改&#xff1b; class Edge(tuple):def __new__(cls, e1, e2):return tuple…

java彈出虛擬鍵盤_JS實現電腦虛擬鍵盤的操作

本文實例為大家分享了JS實現電腦虛擬鍵盤的具體代碼&#xff0c;供大家參考&#xff0c;具體內容如下需求&#xff1a;1.當輸入框光標聚焦時&#xff0c;電腦虛擬鍵盤彈出2.在輸入框輸入內容時&#xff0c;鍵盤跟著變化具體實現代碼如下&#xff1a;Html部分&#xff1a;電腦鍵…

Apache Mahout:入門

最近&#xff0c;我有一個有趣的問題要解決&#xff1a;如何使用自動化對不同來源的文本進行分類&#xff1f; 前一段時間&#xff0c;我讀到一個有關該項目以及許多其他文本分析工作的項目– Apache Mahout 。 盡管它不是一個非常成熟的版本&#xff08;當前版本為0.4 &#x…

Javascript中最常用的55個經典技巧(轉)

1. οncοntextmenu"window.event.returnValuefalse" 將徹底屏蔽鼠標右鍵 <table border οncοntextmenureturn(false)><td>no</table> 可用于Table 2. <body onselectstart"return false"> 取消選取、防止復制 3. οnpaste"…