Pérangan pisanan terjemahan artikel Java 8 Features – The ULTIMATE Guide . Bagian kapindho ana ing kene (link bisa diganti). Cathetan Editor : Artikel iki diterbitake nalika Java 8 kasedhiya kanggo umum lan kabeh indikasi yen iki pancen versi utama. Ing kene kita wis nyedhiyakake pandhuan Java Code Geeks kanthi akeh kayata Playing with Java 8 – Lambdas and Concurrency , Java 8 Date and Time API Guide: LocalDateTime lan Abstract Class vs Interface in the Java 8 Era . Kita uga nyambung menyang 15 tutorial Java 8 sing kudu diwaca saka sumber liyane . Mesthi wae dideleng sawetara kekurangane, kayata Sisih Peteng Jawa 8 . Dadi, wektune kanggo ngumpulake kabeh fitur utama Java 8 ing sak panggonan kanggo penak. Sekeca!
1. Pambuka
Tanpa mangu-mangu, rilis Java 8 minangka acara paling gedhe wiwit Jawa 5 (dirilis cukup suwe, taun 2004). Iku nggawa akeh fitur anyar kanggo Jawa ing basa, compiler, perpustakaan, alat lan JVM (Java Virtual Machine). Ing tutorial iki, kita bakal nliti owah-owahan kasebut lan nduduhake kasus panggunaan sing beda karo conto ing donya nyata. Pandhuan kasebut kalebu sawetara bagean, sing saben-saben nyathet aspek tartamtu saka platform:- Basa
- Compiler
- Pustaka
- piranti
- Lingkungan Runtime (JVM)
2. Fitur anyar ing Jawa 8
Ing kasus apa wae, Java 8 minangka rilis utama. Kita bisa ujar manawa butuh wektu suwe amarga implementasine fitur sing digoleki saben pangembang Java. Ing bagean iki kita bakal nutupi paling akeh.2.1. Lambdas lan Antarmuka Fungsional
Lambdas (uga dikenal minangka metode pribadi utawa anonim) minangka owah-owahan basa sing paling gedhe lan paling diantisipasi ing kabeh rilis Java 8. Iki ngidini kita nemtokake fungsi minangka argumen metode (kanthi nyatakake fungsi ing sakubenge), utawa nemtokake kode minangka data. : konsep sing dikenal saben pangembang fungsional. pemrograman _ Akeh basa ing platform JVM (Groovy, Scala , ...) duwe lambdas wiwit dina pisanan, nanging pangembang Jawa ora duwe pilihan kajaba makili lambdas liwat kelas anonim. Debat desain lambda njupuk akeh wektu lan gaweyan umum. Nanging pungkasane kompromi ditemokake, sing nyebabake muncule desain ringkes anyar. Ing wangun sing paling gampang, lambda bisa diwakili minangka dhaptar parameter sing dipisahake koma, simbol -> simbol , lan awak. Tuladhane:Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) )
Elinga yen jinis argumen e ditemtokake dening compiler. Kajaba iku, sampeyan bisa kanthi tegas nemtokake jinis parameter kanthi mbungkus parameter kasebut ing kurung. Tuladhane:
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e ) );
Yen awak lambda luwih rumit, bisa dibungkus nganggo kurung kriting, padha karo definisi fungsi biasa ing Jawa. Tuladhane:
Arrays.asList( "a", "b", "d" ).forEach( e -< {
System.out.print( e );
System.out.print( e );
} );
A lambda bisa ngrujuk marang anggota kelas lan variabel lokal (implicitly nggawe telpon efektif preduli saka apa final
lapangan diakses utawa ora). Contone, 2 cuplikan iki padha karo:
String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
( String e ) -> System.out.print( e + separator ) );
LAN:
final String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
( String e ) -> System.out.print( e + separator ) );
Lambdas bisa ngasilake nilai. Jinis bali bakal ditemtokake dening compiler. Pranyatan return
ora dibutuhake yen awak lambda kasusun saka siji baris. Loro cuplikan kode ing ngisor iki padha karo:
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
LAN:
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
int result = e1.compareTo( e2 );
return result;
} );
Pangembang basa wis suwe mikir babagan carane nggawe fungsi sing wis ana sing ramah lambda. Akibaté, konsep antarmuka fungsional muncul. Antarmuka fungsional minangka antarmuka kanthi mung siji cara. Akibaté, bisa diowahi sacara implisit dadi ekspresi lambda. java.lang.Runnable
lan java.util.concurrent.Callable
loro conto gedhe saka antarmuka fungsi. Ing praktik, antarmuka fungsional banget rapuh: yen ana wong sing nambahake siji cara liyane menyang definisi antarmuka, mula ora bisa digunakake maneh lan proses kompilasi ora bakal rampung. Kanggo ngindhari fragility iki lan kanthi jelas nemtokake maksud antarmuka minangka fungsional, anotasi khusus ditambahake ing Jawa 8 @FunctionalInterface
(kabeh antarmuka sing ana ing perpustakaan Jawa nampa anotasi @FunctionalInterface). Ayo goleki definisi prasaja antarmuka fungsional iki:
@FunctionalInterface
public interface Functional {
void method();
}
Ana siji bab sing kudu dieling-eling: metode standar lan metode statis ora nglanggar prinsip antarmuka fungsional lan bisa diumumake:
@FunctionalInterface
public interface FunctionalDefaultMethods {
void method();
default void defaultMethod() {
}
}
Lambdas minangka fitur sing paling populer ing Jawa 8. Dheweke duwe kabeh potensi kanggo narik luwih akeh pangembang menyang platform sing apik iki lan nyedhiyakake dhukungan cerdas kanggo fitur ing Jawa murni. Kanggo informasi sing luwih rinci, waca dokumentasi resmi .
2.2. Antarmuka Default lan Metode Statis
Java 8 ngembangake definisi antarmuka kanthi rong konsep anyar: metode standar lan metode statis. Cara standar nggawe antarmuka rada padha karo sipat, nanging nduweni tujuan sing rada beda. Iki ngidini sampeyan nambahake cara anyar menyang antarmuka sing wis ana tanpa ngrusak kompatibilitas mundur kanggo versi antarmuka kasebut sing wis ditulis sadurunge. Bedane metode standar lan metode abstrak yaiku metode abstrak kudu dileksanakake nalika metode standar ora. Nanging, saben antarmuka kudu nyedhiyakake implementasine sing diarani standar, lan kabeh turunane bakal nampa kanthi gawan (kanthi kemampuan kanggo ngatasi implementasi standar iki yen perlu). Coba deleng conto ing ngisor iki.private interface Defaulable {
// Интерфейсы теперь разрешают методы по умолчанию,
// клиент может реализовывать (переопределять)
// or не реализовывать его
default String notRequired() {
return "Default implementation";
}
}
private static class DefaultableImpl implements Defaulable {
}
private static class OverridableImpl implements Defaulable {
@Override
public String notRequired() {
return "Overridden implementation";
}
}
Antarmuka Defaulable
ngumumake metode standar notRequired()
nggunakake tembung kunci default
minangka bagean saka definisi metode. Salah sawijining kelas, DefaultableImpl
, ngleksanakake antarmuka iki ninggalake cara standar minangka. kelas liyane, OverridableImpl
, overrides implementasine gawan lan menehi dhewe. Fitur menarik liyane sing dikenalake ing Jawa 8 yaiku antarmuka bisa ngumumake (lan nawakake implementasine) metode statis. Iki contone:
private interface DefaulableFactory {
// Interfaces now allow static methods
static Defaulable create( Supplier<Defaulable> supplier ) {
return supplier.get();
}
}
Sepotong kode cilik nggabungake metode standar lan metode statis saka conto ing ndhuwur:
public static void main( String[] args ) {
Defaulable defaulable = DefaulableFactory.create( DefaultableImpl::new );
System.out.println( defaulable.notRequired() );
defaulable = DefaulableFactory.create( OverridableImpl::new );
System.out.println( defaulable.notRequired() );
}
Output console saka program iki katon kaya iki:
Default implementation
Overridden implementation
Implementasi metode standar ing JVM efisien banget lan invocation metode didhukung dening instruksi bytecode. Cara standar ngidini antarmuka Jawa sing wis ana bisa berkembang tanpa ngrusak proses kompilasi. Conto sing apik yaiku akeh metode sing ditambahake ing antarmuka java.util.Collection
: stream()
, parallelStream()
, forEach()
, removeIf()
, ... Sanajan kuat, metode standar kudu digunakake kanthi ati-ati: sadurunge nyatakake metode standar, sampeyan kudu mikir kaping pindho apa iki pancene perlu amarga iki bisa nyebabake. kanggo kompilasi ambiguitas lan kesalahan ing hirarki kompleks. Kanggo informasi sing luwih rinci, waca dokumentasi .
2.3. Metode referensi
Metode referensi ngleksanakake sintaksis sing migunani kanggo ngrujuk metode utawa konstruktor kelas utawa obyek Jawa sing wis ana. Bebarengan karo ekspresi lambda, metode referensi nggawe konstruksi basa sing kompak lan ringkes, dadi basis cithakan. Ing ngisor iki kelasCar
minangka conto definisi metode sing beda-beda, ayo nyorot papat jinis metode referensi sing didhukung:
public static class Car {
public static Car create( final Supplier<Car> supplier ) {
return supplier.get();
}
public static void collide( final Car car ) {
System.out.println( "Collided " + car.toString() );
}
public void follow( final Car another ) {
System.out.println( "Following the " + another.toString() );
}
public void repair() {
System.out.println( "Repaired " + this.toString() );
}
}
Cara referensi pisanan minangka referensi kanggo konstruktor kanthi sintaks Class::new
utawa alternatif kanggo generik Class< T >::new
. Elinga yen konstruktor ora duwe argumen.
final Car car = Car.create( Car::new );
final List<Car> cars = Arrays.asList( car );
Opsi kapindho yaiku referensi kanggo metode statis kanthi sintaks Class::static_method
. Elinga yen cara njupuk persis siji parameter saka jinis Car
.
cars.forEach( Car::collide );
Jinis kaping telu minangka referensi kanggo metode instance saka obyek arbitrer saka jinis tartamtu kanthi sintaks Class::method
. Elinga yen ora ana argumen sing ditampa kanthi metode kasebut.
cars.forEach( Car::repair );
Lan pungkasan, jinis kaping papat minangka referensi kanggo metode conto kelas tartamtu kanthi sintaks instance::method
. Wigati dimangerteni manawa metode kasebut mung nampa siji jinis parameter Car
.
final Car police = Car.create( Car::new );
cars.forEach( police::follow );
Nglakokake kabeh conto iki minangka program Java ngasilake output konsol ing ngisor iki (referensi kelas Car
bisa beda-beda):
Collided com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Repaired com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Following the com.javacodegeeks.java8.method.references.MethodReferences$Car@7a81197d
Kanggo informasi sing luwih rinci lan rincian cara referensi, waca dokumentasi resmi .
2.4. Anotasi duplikat
Wiwit Java 5 ngenalake dhukungan kanggo anotasi , fitur iki dadi populer lan akeh digunakake. Nanging, salah sawijining watesan nggunakake anotasi yaiku kasunyatan manawa anotasi sing padha ora bisa diumumake luwih saka sepisan ing panggonan sing padha. Java 8 nglanggar aturan iki lan ngenalake anotasi duplikat. Iki ngidini anotasi sing padha bisa diulang kaping pirang-pirang ing lokasi sing diumumake. Anotasi duplikat kudu menehi anotasi kanthi nggunakake anotasi@Repeatable
. Ing kasunyatan, iki ora dadi luwih owah-owahan ing basa minangka trick compiler, nalika technique tetep padha. Ayo katon ing conto prasaja:
package com.javacodegeeks.java8.repeatable.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class RepeatingAnnotations {
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
public @interface Filters {
Filter[] value();
}
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
@Repeatable( Filters.class )
public @interface Filter {
String value();
};
@Filter( "filter1" )
@Filter( "filter2" )
public interface Filterable {
}
public static void main(String[] args) {
for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) {
System.out.println( filter.value() );
}
}
}
Kaya sing kita deleng, kelas kasebut Filter
dianotasi karo @Repeatable ( Filters. class
). Filters
iku mung pemilik saka anotasi Filter
, nanging compiler Jawa nyoba kanggo ndhelikake ngarsane saka pangembang. Mangkono, antarmuka Filterable
ngemot anotasi Filter
sing diumumake kaping pindho (tanpa nyebutake Filters
). Reflection API uga menehi cara anyar getAnnotationsByType()
kanggo bali duplikat anotasi saka sawetara jinis (elinga sing Filterable. class
.getAnnotation ( Filter. class
) bakal ngasilake conto compiler-nyuntikaken Filters
). Output saka program bakal katon kaya iki:
filter1
filter2
Kanggo informasi sing luwih rinci, waca dokumentasi resmi .
2.5. Inferensi jinis apik
Compiler Java 8 wis nampa akeh dandan inferensi jinis. Ing sawetara kasus, paramèter jinis eksplisit bisa ditetepake dening compiler, saéngga nggawe kode luwih resik. Ayo ndeleng siji conto:package com.javacodegeeks.java8.type.inference;
public class Value<T> {
public static<T> T defaultValue() {
return null;
}
public T getOrDefault( T value, T defaultValue ) {
return ( value != null ) ? value : defaultValue;
}
}
Lan iki nggunakake jinis Value<String>
:
package com.javacodegeeks.java8.type.inference;
public class TypeInference {
public static void main(String[] args) {
final Value<String> value = new Value<>();
value.getOrDefault( "22", Value.defaultValue() );
}
}
Parameter jinis Value.defaultValue()
ditemtokake kanthi otomatis lan ora perlu diwenehake kanthi jelas. Ing Jawa 7, conto sing padha ora bakal dikompilasi lan kudu ditulis maneh minangka <NOBR>Value.<String>defaultValue()</NOBR>.
2.6. Dhukungan anotasi sing ditambahi
Java 8 ngembangake konteks ing ngendi anotasi bisa digunakake. Saiki, meh kabeh bisa duwe anotasi: variabel lokal, jinis umum, superclass lan antarmuka sing diimplementasikake, malah pengecualian metode. Sawetara conto ditampilake ing ngisor iki:package com.javacodegeeks.java8.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collection;
public class Annotations {
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE_USE, ElementType.TYPE_PARAMETER } )
public @interface NonEmpty {
}
public static class Holder<@NonEmpty T> extends @NonEmpty Object {
public void method() throws @NonEmpty Exception {
}
}
@SuppressWarnings( "unused" )
public static void main(String[] args) {
final Holder<String> holder = new @NonEmpty Holder<String>();
@NonEmpty Collection<@NonEmpty String> strings = new ArrayList<>();
}
}
ElementType.TYPE_USE
lan ElementType.TYPE_PARAMETER
rong jinis unsur anyar kanggo njlèntrèhaké konteks anotasi sing cocog. Annotation Processing API
uga ngalami owah-owahan cilik kanggo ngenali jinis anotasi anyar ing Jawa.
3. Fitur anyar ing compiler Jawa
3.1. Jeneng parameter
Saindhenging wektu, pangembang Jawa wis nemokke macem-macem cara kanggo nyimpen jeneng parameter metode ing bytecode Jawa supaya kasedhiya ing runtime (contone, perpustakaan Paranamer ). Pungkasan, Java 8 nggawe fungsi sing angel iki ing basa (nggunakake Reflection API lan metodeParameter.getName()
) lan bytecode (nggunakake argumen kompiler anyar javac
:) –parameters
.
package com.javacodegeeks.java8.parameter.names;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class ParameterNames {
public static void main(String[] args) throws Exception {
Method method = ParameterNames.class.getMethod( "main", String[].class );
for( final Parameter parameter: method.getParameters() ) {
System.out.println( "Parameter: " + parameter.getName() );
}
}
}
Yen sampeyan ngumpulake kelas iki tanpa nggunakake argumen –parameters
lan banjur mbukak program, sampeyan bakal weruh kaya iki:
Parameter: arg0
Kanthi parameter –parameters
sing diterusake menyang kompiler, output program bakal beda-beda (jeneng parameter sing bener bakal ditampilake):
Parameter: args
Kanggo pangguna Maven sing luwih maju, argumen -parameter bisa ditambahake menyang kompilasi nggunakake bagean maven-compiler-plugin
:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
Kanggo mriksa kasedhiyan jeneng parameter ana isNamePresent()
cara trep sing diwenehake dening kelas Parameter
.
4. Piranti Jawa Anyar
Java 8 dilengkapi piranti baris printah anyar. Ing bagean iki kita bakal katon ing paling menarik saka wong-wong mau.4.1. Nashorn engine: js
jjs minangka mesin Nashorn mandiri sing adhedhasar baris printah. Butuh dhaptar file kode sumber JavaScript lan mbukak. Contone, ayo nggawe file func.js kanthi isi ing ngisor iki:function f() {
return 1;
};
print( f() + 1 );
Kanggo mbukak file iki, ayo ngirim minangka argumen menyang jjs :
jjs func.js
Output konsol bakal kaya iki:
2
Kanggo rincian liyane ndeleng dokumentasi .
4.2. Analyzer Ketergantungan Kelas: jdeps
jdeps minangka alat baris perintah sing apik banget. Iki nuduhake dependensi tingkat paket utawa kelas kanggo kelas Jawa. Iku nampa file .class , folder utawa file JAR minangka input. Kanthi gawan , jdeps ngasilake dependensi menyang output standar (konsol). Minangka conto, ayo ndeleng laporan dependensi saka perpustakaan Spring Framework sing populer . Supaya contone tetep cendhak, ayo goleki dependensi kanggo file JAR mungorg.springframework.core-3.0.5.RELEASE.jar
.
jdeps org.springframework.core-3.0.5.RELEASE.jar
Printah iki ngasilake cukup akeh, mula kita mung bakal nganalisa bagean saka output kasebut. Dependensi diklompokaké miturut paket. Yen ora ana dependensi, ora ditemokake bakal ditampilake .
org.springframework.core-3.0.5.RELEASE.jar -> C:\Program Files\Java\jdk1.8.0\jre\lib\rt.jar
org.springframework.core (org.springframework.core-3.0.5.RELEASE.jar)
-> java.io
-> java.lang
-> java.lang.annotation
-> java.lang.ref
-> java.lang.reflect
-> java.util
-> java.util.concurrent
-> org.apache.commons.logging not found
-> org.springframework.asm not found
-> org.springframework.asm.commons not found
org.springframework.core.annotation (org.springframework.core-3.0.5.RELEASE.jar)
-> java.lang
-> java.lang.annotation
-> java.lang.reflect
-> java.util
Kanggo informasi sing luwih rinci, waca dokumentasi resmi .
GO TO FULL VERSION