java 反编译项目_Java 7 –反编译项目硬币
java 反編譯項目
大家好,該是從2012年開始寫作的時候了。正如您在其他博客中可能已經(jīng)看到的那樣,有一些更改可以使您使用Java編程時的開發(fā)人員生活變得更加輕松:Diamond運算符,Switchs中的Strings,嘗試使用資源,多次捕獲等在本文(PART I)中,我們將看到Java 7 Project Coin(JSR 334)中提出的一些小改動,然后(在第二部分中)我們將對它們進(jìn)行反編譯,以查看編譯器在做什么(對于僅用于教育目的)。
你需要什么
- NetBeans 7+或任何其他支持Java 7的IDE
- JSDK 7+
- JAD反編譯 [R 或 Java的反編譯
鉆石算子
泛型幫助我們減少了ClassCastExceptions,但是有時候它會使代碼難以閱讀。 鉆石算子是一個非常不錯的變化。 成像您需要按城市對客戶進(jìn)行分組。 您將需要以下內(nèi)容:
//suppose the classes City and Customer exist ... Map<City,List<Customer>> map = new HashMap<City,List<Customer>>(); ...現(xiàn)在,如果您還需要按國家/地區(qū)對數(shù)據(jù)進(jìn)行分組怎么辦:
//suppose the classes Country, City and Customer exist ... Map<Country,MapltCity,List<Customer>>> map = new HashMapl&t;Country,MapltCity,ListltCustomer>>>(); ...現(xiàn)在,它開始變得很難閱讀,對吧? 如果您還需要按地區(qū)分組怎么辦?
//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<>(); ...好了很多!
開關(guān)中的弦
我已經(jīng)等了很多!!! 我還記得我剛開始Java時代的日子,我確實需要在switch中使用Strings。 好吧,我的等待終于結(jié)束了。 在Java的早期版本中,您必須編寫如下代碼:
在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也可以選擇自動轉(zhuǎn)換:
嘗試使用資源和多重捕獲
在此版本中,這是一個不錯的增強,現(xiàn)在您不必?fù)?dān)心關(guān)閉那些ResultSet,States,FileInputStreams等。 您只需要使用新的try結(jié)構(gòu),編譯器就會為您處理它。 您甚至可以通過新的try結(jié)構(gòu)將自己的類創(chuàng)建為Closeable(這是一個新接口)。 以下是通過流進(jìn)行的經(jīng)典文件訪問:
//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;}} ...如果您注意到了,為了確保打開的流一旦完成就被關(guān)閉,則必須編寫一個try / finally塊并自己關(guān)閉它們。 在Java 7中,可以使用新的try結(jié)構(gòu)和新的NIO.2類以更好的方式和更少的代碼行實現(xiàn)相同的行為:
//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;} } ...二進(jìn)制文字和下劃線
現(xiàn)在,您可以將整數(shù)表示為二進(jìn)制文字,這在編程低級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 } ...因此,更少的代碼,更高的生產(chǎn)率和更好的代碼可讀性是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現(xiàn)在,讓我們看看編譯器生成的代碼是什么樣的:
import java.util.*; ... java.util.Map map = new HashMap(); ...只是一個舊學(xué)校地圖的定義和實例化...為什么? 因為這就是泛型的工作方式:
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.這意味著編譯器將在編譯時檢查您是否使用了正確的類,并將任何必要的強制轉(zhuǎn)換添加到生成的類中。 例如:
//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您將獲得如下內(nèi)容:
//suppose the class Region exists import java.util.*; ... Map map = new HashMap(); Map m = (Map)map.get(new Region()); //the compiler added the cast ...開關(guān)中的弦
記住上一篇文章中介紹的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;} } ...反編譯之后,您會注意到開關(guān)狀態(tài)菜單現(xiàn)在如何支持字符串:
//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是整數(shù))。 通過查看代碼,我意識到最好不要在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資源,并進(jìn)行多捕獲。 當(dāng)我嘗試使用JAD Java Decompiler對生成的類進(jìn)行反編譯時,我對嵌套的try語句有很多誤解,因此我決定嘗試JD Java Decompiler,結(jié)果如下:
//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來確保復(fù)制過程中拋出的任何異常都不會丟失。 這很重要,因為在應(yīng)用程序中查找錯誤時,您將需要所有可能的異常。 另外,請注意,所有關(guān)閉操作都是在finally語句中完成的,以確保在過程結(jié)束時始終關(guān)閉資源。
二進(jìn)制文字和下劃線
我認(rèn)為您可以弄清楚反編譯此最后一個功能后會得到什么……
//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 } ...是的,沒有什么新東西了……編譯器只重寫沒有下劃線的值,并將二進(jìn)制值轉(zhuǎn)換為整數(shù)值:
//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還有更多改進(jìn),我們將在以后的文章中進(jìn)行檢查。 拜拜!
參考:我們的JCG合作伙伴提供的 Java –項目硬幣反編譯和Java 7 –項目硬幣反編譯第二部分 Java和ME博客上的Alexis Lopez。
翻譯自: https://www.javacodegeeks.com/2012/04/java-7-project-coin-decompiled.html
java 反編譯項目
總結(jié)
以上是生活随笔為你收集整理的java 反编译项目_Java 7 –反编译项目硬币的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为移动路由Pro评测华为如何测试路由器
- 下一篇: Java 9代码工具:使用Java微型基