史上最全jdk版本新特性大全
前言
在本文中,我將描述自第8版以來Java最重要且對開發人員友好的功能。為什么會有這樣的主意?在Web上,您可以找到許多文章,其中包含每種Java版本的新功能列表。但是,由于缺少文章,因此無法簡要概述自第8版以來最重要的更改。好的,但是為什么是第8版?令人驚訝的是,它仍然是最常用的Java版本。即使我們已經到了Java 16發行版的前夕。如您所見,超過46%的響應者仍在生產中使用Java 8。相比之下,只有不到10%的響應者使用Java 12或更高版本。
java版本使用占比那接下來咋們從JDK8到JDK15,給大家介紹新的JDK提供給咋們的新特性!
?
JDK8
Lambda表達式
最直接作用就是減少代碼,代碼直接減少50%+,顯得非常簡潔
?//使用java匿名內部類Comparator<Integer>?cpt?=?new?Comparator<Integer>()?{@Overridepublic?int?compare(Integer?o1,?Integer?o2)?{return?Integer.compare(o1,o2);}};TreeSet<Integer>?set?=?new?TreeSet<>(cpt);System.out.println("=========================");//使用JDK8?lambda表達式Comparator<Integer>?cpt2?=?(x,y)?->?Integer.compare(x,y);TreeSet<Integer>?set2?=?new?TreeSet<>(cpt2);//?java7中??篩選產品為nike的 public??List<Product>?filterProductByColor(List<Product>?list){List<Product>?prods?=?new?ArrayList<>();for?(Product?product?:?list){if?("nike".equals(product.getName())){prods.add(product);}}return?prods;}//?使用?lambda public??List<Product>?filterProductByPrice(List<Product>?list){return?list.stream().filter(p->"nike".equals(p.getName())).collect(Collectors.toList());??}函數式接口
位于java.util.function包下,下面介紹最常用的幾個
Predicate
接收一個值返回boolean
??Predicate?p?=?t->true;Supplier
無接受參數返回一個值
Supplier<T>?s?=?()?->?new?T();Consumer
接受一個參數無返回值
Consumer<String>?c?=?c?->?System.out.println(s);Function<T,R>
接受參數T 返回參數R
Function<Long,String>?f?=?c?->?String.valueof(c);其他還有一個 BiFunction,BiConsumer,DoubleSupplier等大家有興趣自己去閱讀下源碼
方法引用
靜態引用:格式:Class::static_method
構造器調用 構造器方法引用格式:Class::new,調用默認構造器
方法調用 格式:instance::method
Stream API
接口中的默認方法和靜態方法
Optional
用于處理對象空指針異常:
??public?String?getDesc(Test?test){return?Optional.ofNullable(test).map(Test::getDesc).else("");}?
?
JDK9
收集工廠方法
借助Java 9的一項新功能,即集合工廠方法,您可以輕松地使用預定義的數據創建不可變的集合。您只需要在特定集合類型上使用of方法。
List<String>?fruits?=?List.of("apple",?"banana",?"orange"); Map<Integer,?String>?numbers?=?Map.of(1,?"one",?2,"two",?3,?"three");在Java 9之前,您可以使用Collections,但這絕對是一種更復雜的方法。
public?List<String>?fruits()?{List<String>?fruitsTmp?=?new?ArrayList<>();fruitsTmp.add("apple");fruitsTmp.add("banana");fruitsTmp.add("orange");return?Collections.unmodifiableList(fruitsTmp); }public?Map<Integer,?String>?numbers()?{Map<Integer,?String>?numbersTmp?=?new?HashMap<>();numbersTmp.put(1,?"one");numbersTmp.put(2,?"two");numbersTmp.put(3,?"three");return?Collections.unmodifiableMap(numbersTmp); }同樣,僅從ArrayList對象表創建即可使用Arrays.asList(...)method。
public?List<String>?fruitsFromArray()?{String[]?fruitsArray?=?{"apple",?"banana",?"orange"};return?Arrays.asList(fruitsArray); }接口中的私有方法
從Java 8開始,您可以在接口內部使用公共默認方法。但是僅從Java 9開始,由于接口中的私有方法,您將能夠充分利用此功能。
ublic?interface?ExampleInterface?{private?void?printMsg(String?methodName)?{System.out.println("Calling?interface");System.out.println("Interface?method:?"?+?methodName);}default?void?method1()?{printMsg("method1");}default?void?method2()?{printMsg("method2");} }?
?
JDK10
從Java 9和Java 10開始,有幾種用于Optional的有用方法。其中最有趣的兩個是orElseThrow和ifPresentOrElse。如果沒有值,則使用該orElseThrow方法拋出NoSuchElementException。否則,它返回一個值。
public?Person?getPersonById(Long?id)?{Optional<Person>?personOpt?=?repository.findById(id);return?personOpt.orElseThrow(); }因此,您可以避免將帶參數的if語句與isPresentmethod一起使用。
public?Person?getPersonByIdOldWay(Long?id)?{Optional<Person>?personOpt?=?repository.findById(id);if?(personOpt.isPresent())return?personOpt.get();elsethrow?new?NoSuchElementException(); }第二種有趣的方法是ifPresentOrElse。如果存在一個值,它將使用該值執行給定的操作。否則,它將執行給定的基于空的操作。
public?void?printPersonById(Long?id)?{Optional<Person>?personOpt?=?repository.findById(id);personOpt.ifPresentOrElse(System.out::println,()?->?System.out.println("Person?not?found")); }在Java 8中,我們可以if-else直接與isPresent方法一起使用。
public?void?printPersonByIdOldWay(Long?id)?{Optional<Person>?personOpt?=?repository.findById(id);if?(personOpt.isPresent())System.out.println(personOpt.get());elseSystem.out.println("Person?not?found"); }?
?
JDK 10 && JDK 11
從Java 10開始,您可以聲明沒有其類型的局部變量。您只需要定義var關鍵字而不是類型。從Java 11開始,您還可以將其與lambda表達式一起使用,如下所示。
public?String?sumOfString()?{BiFunction<String,?String,?String>?func?=?(var?x,?var?y)?->?x?+?y;return?func.apply("abc",?"efg"); }?
?
JDK 12
使用Switch表達式,您可以定義多個case標簽并使用箭頭返回值。此功能自JDK 12起可用。它使Switch表達式真正更易于訪問。
??public?String?newMultiSwitch(int?day)?{return?switch?(day)?{case?1,?2,?3,?4,?5?->?"workday";case?6,?7?->?"weekend";default?->?"invalid";};}對于低于12的Java,相同的示例要復雜得多。
public?String?oldMultiSwitch(int?day)?{switch?(day)?{case?1:case?2:case?3:case?4:case?5:return?"workday";case?6:case?7:return?"weekend";default:return?"invalid";}}?
?
JDK 13
文本塊是多行字符串文字,它避免使用轉義序列,并以可預測的方式自動設置字符串格式。它還使開發人員可以控制字符串的格式。從Java 13開始,文本塊可用作預覽功能。它們以三個雙引號(""")開頭。讓我們看看我們如何輕松地創建和格式化JSON消息。
????public?String?getNewPrettyPrintJson()?{return?"""{"firstName":?"Piotr","lastName":?"Mińkowski"}""";}創建Java 13之前的相同JSON字符串要復雜得多。
???public?String?getOldPrettyPrintJson()?{return?"{\n"?+"?????\"firstName\":?\"Piotr\",\n"?+"?????\"lastName\":?\"Mińkowski\"\n"?+"}";}?
?
JDK14
使用Records,您可以定義不可變的純數據類(僅限getter)。它會自動創建toString,equals和hashCode方法。實際上,您只需要定義如下所示的字段即可。
public?record?Person(String?name,?int?age)?{}具有類似功能的類如record包含字段,構造函數,getter和實施toString,equals以及hashCode方法。
public?class?PersonOld?{private?final?String?name;private?final?int?age;public?PersonOld(String?name,?int?age)?{this.name?=?name;this.age?=?age;}public?String?getName()?{return?name;}public?int?getAge()?{return?age;}@Overridepublic?boolean?equals(Object?o)?{if?(this?==?o)?return?true;if?(o?==?null?||?getClass()?!=?o.getClass())?return?false;PersonOld?personOld?=?(PersonOld)?o;return?age?==?personOld.age?&&?name.equals(personOld.name);}@Overridepublic?int?hashCode()?{return?Objects.hash(name,?age);}@Overridepublic?String?toString()?{return?"PersonOld{"?+"name='"?+?name?+?'\''?+",?age="?+?age?+'}';}}?
?
JDK15
使用密封類功能,您可以限制超類的使用。使用new關鍵字,sealed您可以定義哪些其他類或接口可以擴展或實現當前類。
public?abstract?sealed?class?Pet?permits?Cat,?Dog?{}允許的子類必須定義一個修飾符。如果您不想允許任何其他擴展名,則需要使用final關鍵字。
public?final?class?Cat?extends?Pet?{}另一方面,您可以打開擴展類。在這種情況下,應使用non-sealed修飾符。
public?non-sealed?class?Dog?extends?Pet?{}當然,下面的可見聲明是不允許的。
public?final?class?Tiger?extends?Pet?{}有道無術,術可成;有術無道,止于術
歡迎大家關注Java之道公眾號
好文章,我在看??
總結
以上是生活随笔為你收集整理的史上最全jdk版本新特性大全的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 001.Amoeba读写分离部署
- 下一篇: EasyNVR支持的摄像机、NVR设备接