Java SE8結(jié)構(gòu)與新增功能

Java8簡介

????????摘自官文文檔
????????Oracle的Java SE8包含了兩個產(chǎn)品:Java SE開發(fā)套件(JDK)8和Java SE運行環(huán)境(JRE)8翁脆。
????????JDK8是JRE8的超集筑悴,它包含了JRE8中所含有的一切魏宽,以及開發(fā)applet和應(yīng)用程序所需的編譯器和調(diào)試器等工具呆馁。JRE8提供了運行用java程序語言編寫的applets和程序所需要的類庫梗摇,java虛擬機(jvm)和其他組件。需要注意的是几缭,JRE包含Java SE規(guī)范不需要的組件河泳,包括標準和非標準Java組件。
????????以下概念圖說明了Oracle Java SE產(chǎn)品的組件:
????????Java概念圖

java概念圖

Java7年栓,Java8新增功能

摘自官方文檔

Java7新增功能

  • Binary Literals——在Java7中拆挥,整型(byte, short, int and long)也可以使用二進制數(shù)字進行表示。要指定二進制表示某抓,只需在數(shù)字添加0b或者0B前綴纸兔。示例代碼:
// An 8-bit 'byte' value:
byte aByte = (byte)0b00100001;

// A 16-bit 'short' value:
short aShort = (short)0b1010000101000101;

// Some 32-bit 'int' values:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case.

// A 64-bit 'long' value. Note the "L" suffix:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
  • Underscores in Numeric Literals——任意數(shù)量的下劃線‘_’可以出現(xiàn)在數(shù)字文本中的任意位置。這個特性可以讓你對數(shù)字文本切割分組搪缨,這樣可以提升代碼的可讀性食拜。示例代碼:
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi =      3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

注意!你不能在如下場景下使用:

  1. 不能在文字的開頭或結(jié)尾使用下劃線副编!
  2. 不能與浮點數(shù)中的小數(shù)點相鄰负甸!
  3. 不能在L或F后綴之前使用!
  4. 不能在預(yù)期是一串?dāng)?shù)字的位置上使用痹届!
    示例代碼:
float pi1 = 3_.1415F;      // Invalid; cannot put underscores adjacent to a decimal point
float pi2 = 3._1415F;      // Invalid; cannot put underscores adjacent to a decimal point
long socialSecurityNumber1
  = 999_99_9999_L;         // Invalid; cannot put underscores prior to an L suffix

int x1 = _52;              // This is an identifier, not a numeric literal
int x2 = 5_2;              // OK (decimal literal)
int x3 = 52_;              // Invalid; cannot put underscores at the end of a literal
int x4 = 5_______2;        // OK (decimal literal)

int x5 = 0_x52;            // Invalid; cannot put underscores in the 0x radix prefix
int x6 = 0x_52;            // Invalid; cannot put underscores at the beginning of a number
int x7 = 0x5_2;            // OK (hexadecimal literal)
int x8 = 0x52_;            // Invalid; cannot put underscores at the end of a number

int x9 = 0_52;             // OK (octal literal)
int x10 = 05_2;            // OK (octal literal)
int x11 = 052_;            // Invalid; cannot put underscores at the end of a number
public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
     String typeOfDay;
     switch (dayOfWeekArg) {
         case "Monday":
             typeOfDay = "Start of work week";
             break;
         case "Tuesday":
         case "Wednesday":
         case "Thursday":
             typeOfDay = "Midweek";
             break;
         case "Friday":
             typeOfDay = "End of work week";
             break;
         case "Saturday":
         case "Sunday":
             typeOfDay = "Weekend";
             break;
         default:
             throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
     }
     return typeOfDay;
}
  • Type Inference for Generic Instance Creation——你可以使用一組空類型參數(shù)(<>)替換調(diào)用泛型類的構(gòu)造函數(shù)所需的類型參數(shù),只要編譯器可以從上下文中推斷出類型參數(shù)队腐。示例代碼:
//Java7之前
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
//Java7
Map<String, List<String>> myMap = new HashMap<>();

/*Java SE 7 supports limited type inference for generic instance creation; 
you can only use type inference if the parameterized type of the constructor is 
obvious from the context.*/
List<String> list = new ArrayList<>();
list.add("A");
  // The following statement should fail since addAll expects
  // Collection<? extends String>
list.addAll(new ArrayList<>());
/*Note that the diamond often works in method calls; 
however, it is suggested that you use the diamond primarily for variable declarations.*/
// The following statements compile:
List<? extends String> list2 = new ArrayList<>();
list.addAll(list2);
  • Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods——Java7編譯器會在那些有一個non-reifiable類型可變參數(shù)的方法或者構(gòu)造器聲明點生成一個警告蚕捉。Java7采用編譯選項-Xlint:varargs和這些注解@SafeVarargs@SuppressWarnings({"unchecked", "varargs"})來壓制這個警告柴淘。
    原文:The Java SE 7 complier generates a warning at the declaration site of a varargs method or constructor with a non-reifiable varargs formal parameter. Java SE 7 introduces the compiler option -Xlint:varargs and the annotations @SafeVarargs and @SuppressWarnings({"unchecked", "varargs"}) to suppress these warnings.

non-reifiable類型是指在運行期無法完全獲得的類型迫淹,例如ArrayList<Number>List<String>等等。
原文:Most parameterized types, such as ArrayList<Number> and List<String>, are non-reifiable types. A non-reifiable type is a type that is not completely available at runtime.
示例代碼:

public class ArrayBuilder {

  public static <T> void addToList (List<T> listArg, T... elements) {
    for (T x : elements) {
      listArg.add(x);
    }
  }

  @SuppressWarnings({"unchecked", "varargs"})
  public static <T> void addToList2 (List<T> listArg, T... elements) {
    for (T x : elements) {
      listArg.add(x);
    }
  }

  @SafeVarargs
  public static <T> void addToList3 (List<T> listArg, T... elements) {
    for (T x : elements) {
      listArg.add(x);
    }
  }

  // ...

}
public class HeapPollutionExample {

  // ...

  public static void main(String[] args) {

    // ...

    ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB);
    ArrayBuilder.addToList2(listOfStringLists, stringListA, stringListB);
    ArrayBuilder.addToList3(listOfStringLists, stringListA, stringListB);

    // ...

  }
}
  • The try-with-resources Statement——try-with-resources表達式是一個定義了一個或多個資源的try表達式为严。一個資源指的是一個在程序結(jié)束時必須要調(diào)用close方法進行關(guān)閉的對象敛熬。try-with-resource表達式可以確保每個資源都會在表達式最后進行關(guān)閉。任何一個實現(xiàn)了java.lang.AutoCloseable或者java.io.Closeable接口的對象都可以看做一個資源第股。這些類应民,java.io.InputStream, OutputStream, Reader, Writer, java.sql.Connection, Statement, ResultSet都可以在try-with-resources表達式中被當(dāng)做資源進行使用,因為它們都實現(xiàn)了AutoCloseable接口夕吻。示例代碼:
//定義一個資源
static String readFirstLineFromFile(String path) throws IOException {
  try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
  }
}

//定義多個資源
 public static void writeToFileZipFileContents(String zipFileName, String outputFileName)
    throws java.io.IOException {

    java.nio.charset.Charset charset = java.nio.charset.StandardCharsets.US_ASCII;
    java.nio.file.Path outputFilePath = java.nio.file.Paths.get(outputFileName);

    // Open zip file and create output file with try-with-resources statement
    try (
      java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
      java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {

      // Enumerate each entry
      for (java.util.Enumeration entries = zf.entries(); entries.hasMoreElements();) {

        // Get the entry name and write it to the output file

        String newLine = System.getProperty("line.separator");
        String zipEntryName = ((java.util.zip.ZipEntry)entries.nextElement()).getName() + newLine;
        writer.write(zipEntryName, 0, zipEntryName.length());
      }
    }
  }
//Handling More Than One Type of Exception
catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

// Rethrowing Exceptions with More Inclusive Type Checking
public void rethrowException(String exceptionName)
  throws FirstException, SecondException {
    try {
      // ...
    }
    catch (Exception e) {
      throw e;
    }
  }

Java8新增功能

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }
    
    public Calendar getBirthday() {
        return birthday;
    }    

    public static int compareByAge(Person a, Person b) {
        return a.birthday.compareTo(b.birthday);
 }}

//Reference to a Static Method
Arrays.sort(rosterAsArray, Person::compareByAge);

//Reference to an Instance Method of a Particular Object
class ComparisonProvider {
    public int compareByName(Person a, Person b) {
        return a.getName().compareTo(b.getName());
    }
        
    public int compareByAge(Person a, Person b) {
        return a.getBirthday().compareTo(b.getBirthday());
    }
}
ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);

//Reference to a Constructor
public static <T, SOURCE extends Collection<T>, DEST extends Collection<T>>
    DEST transferElements(
        SOURCE sourceCollection,
        Supplier<DEST> collectionFactory) {
        
        DEST result = collectionFactory.get();
        for (T t : sourceCollection) {
            result.add(t);
        }
        return result;
}

Set<Person> rosterSetLambda = transferElements(roster, () -> { return new HashSet<>(); });
// or
Set<Person> rosterSet = transferElements(roster, HashSet::new);
// or
Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new);
  • Improved Type Inference——Java編譯器利用目標類型來推斷泛型方法調(diào)用的類型參數(shù)偶翅。表達式的目標類型是Java編譯器所期望的數(shù)據(jù)類型,具體取決于表達式在哪里出現(xiàn)碉渡。舉個例子聚谁,在Java7中,Java編譯器通過賦值語句的目標類型來進行推斷滞诺,而在Java8中形导,通過上下文中使用的目標類型進行類型推斷。示例代碼:
List<String> stringList = new ArrayList<>();
stringList.add("A");

//在java7中這段會編譯出錯
stringList.addAll(Arrays.asList());

????????你可以在以下的Java教程中獲取更多相關(guān)的信息:
????????1. Target Typing in Lambda Expressions
????????2. Type Inference

  • Annotations on Java Types——可以將注釋運用在Java類型的任何地方习霹。與可插拔類型系統(tǒng)結(jié)合使用朵耕,可以對代碼進行更強大的類型校驗。示例代碼:
//Class instance creation expression
new @Interned MyObject();

//Type cast
myString = (@NonNull String) str;

//implements clause
class UnmodifiableList<T> implements
        @Readonly List<@Readonly T> { ... }

//Thrown exception declaration
void monitorTemperature() throws
        @Critical TemperatureException { ... }

????????這種形式的注釋稱為類型注釋淋叶。更多信息請查閱 Type Annotations and Pluggable Type Systems阎曹。

  • Repeating Annotations——在一個定義或類型上允許多次使用同一個注釋。查閱更多資料可參考 Repeating Annotations in the new Annotations lesson in the Java Tutorial煞檩。示例代碼:
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }

@Alert(role="Manager")
@Alert(role="Administrator")
public class UnauthorizedAccessException extends SecurityException { ... }
  • Method Parameter Reflection——你可以通過使用 java.lang.reflect.Executable.getParameters方法來獲取任一方法或構(gòu)造函數(shù)形參的名字处嫌。(由于 Method類和Constructor類繼承了Executable類,所以它們繼承了Executable.getParameters方法斟湃。)然而.class文件默認是不存儲形參的名稱熏迹。為了實際上能夠讓.class文件存儲形參的名稱并且通過Reflection API獲取到形參的名稱,我們需要在javac編譯源文件時加上 -parameters的選項凝赛。你可以參考 Obtaining Names of Method Parameters教程注暗。示例代碼:
public class Annotation {
    
    private static final String  fmt = "%24s: %s%n";
    private String name;
    private String method;
    
    public Annotation(String name, String method){
        this.name = name;
        this.method = method;
    }
    
    public static void main(String[] args) {
        Class<? extends Annotation> clazz = Annotation.class;
        Constructor<?>[] constructors = clazz.getConstructors();
        for(Constructor<?> constructor : constructors){
            for(Parameter p : constructor.getParameters()){
                printParameter(p);
            }
            
        }
    }
    
    public static void printParameter(Parameter p) {
        System.out.format(fmt, "Parameter class", p.getType());
        System.out.format(fmt, "Parameter name", p.getName());
        System.out.format(fmt, "Modifiers", p.getModifiers());
        System.out.format(fmt, "Is implicit?", p.isImplicit());
        System.out.format(fmt, "Is name present?", p.isNamePresent());
        System.out.format(fmt, "Is synthetic?", p.isSynthetic());
    }
}

輸出結(jié)果:


Method Parameter Reflection
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市墓猎,隨后出現(xiàn)的幾起案子捆昏,更是在濱河造成了極大的恐慌,老刑警劉巖陶衅,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屡立,死亡現(xiàn)場離奇詭異,居然都是意外死亡搀军,警方通過查閱死者的電腦和手機膨俐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罩句,“玉大人焚刺,你說我怎么就攤上這事∶爬茫” “怎么了乳愉?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵兄淫,是天一觀的道長。 經(jīng)常有香客問我蔓姚,道長捕虽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任坡脐,我火速辦了婚禮泄私,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘备闲。我一直安慰自己晌端,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布恬砂。 她就那樣靜靜地躺著咧纠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泻骤。 梳的紋絲不亂的頭發(fā)上漆羔,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音瞪讼,去河邊找鬼钧椰。 笑死,一個胖子當(dāng)著我的面吹牛符欠,可吹牛的內(nèi)容都是我干的嫡霞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼希柿,長吁一口氣:“原來是場噩夢啊……” “哼诊沪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起曾撤,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤端姚,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挤悉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渐裸,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年装悲,在試婚紗的時候發(fā)現(xiàn)自己被綠了昏鹃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡诀诊,死狀恐怖洞渤,靈堂內(nèi)的尸體忽然破棺而出属瓣,到底是詐尸還是另有隱情讯柔,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布护昧,位于F島的核電站,受9級特大地震影響捏卓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜怠晴,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一浴捆、第九天 我趴在偏房一處隱蔽的房頂上張望蒜田。 院中可真熱鬧,春花似錦选泻、人聲如沸冲粤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梯捕。三九已至,卻和暖如春窝撵,著一層夾襖步出監(jiān)牢的瞬間傀顾,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工碌奉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留短曾,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓赐劣,卻偏偏與公主長得像嫉拐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子魁兼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355