JavaRush /จาวาบล็อก /Random-TH /คุณสมบัติ Java 8 – สุดยอดคู่มือ (ตอนที่ 1)
0xFF
ระดับ
Донецк

คุณสมบัติ Java 8 – สุดยอดคู่มือ (ตอนที่ 1)

เผยแพร่ในกลุ่ม
ส่วนแรกของการแปลบทความคุณสมบัติJava 8 – The ULTIMATE Guide ตอนที่ 2 มาแล้ว (ลิงค์อาจมีการเปลี่ยนแปลง) คุณสมบัติ Java 8 – สุดยอดคู่มือ (ตอนที่ 1) - 1 หมายเหตุบรรณาธิการ : บทความนี้เผยแพร่ในขณะที่ Java 8 เผยแพร่สู่สาธารณะ และข้อบ่งชี้ทั้งหมดคือนี่เป็นเวอร์ชันหลักจริงๆ ที่นี่เราได้ให้คำแนะนำ Java Code Geeks มากมาย เช่นPlaying with Java 8 – Lambdas and Concurrency , Java 8 Date and Time API Guide: LocalDateTimeและAbstract Class vs. Interface in the Java 8 Era นอกจากนี้เรายังลิงก์ไปยังบทช่วยสอน Java 8 ที่ต้องอ่าน 15 รายการจากแหล่งอื่น แน่นอนว่าเราพิจารณาข้อเสียบางประการ เช่นด้านมืดของ Java 8 ถึงเวลารวบรวมคุณสมบัติหลักทั้งหมดของ Java 8 ไว้ในที่เดียวเพื่อความสะดวกของคุณ สนุก!

1. บทนำ

ไม่ต้องสงสัยเลยว่าการเปิดตัว Java 8ถือเป็นเหตุการณ์ที่ยิ่งใหญ่ที่สุดนับตั้งแต่ Java 5 (เปิดตัวเมื่อนานมาแล้วในปี 2547) มันนำคุณสมบัติใหม่มากมายมาสู่ Java ทั้งในภาษา คอมไพเลอร์ ไลบรารี เครื่องมือ และ JVM (Java Virtual Machine) ในบทช่วยสอนนี้ เราจะดูการเปลี่ยนแปลงเหล่านี้และสาธิตกรณีการใช้งานต่างๆ พร้อมตัวอย่างในชีวิตจริง คู่มือนี้ประกอบด้วยหลายส่วน โดยแต่ละส่วนจะกล่าวถึงแง่มุมเฉพาะของแพลตฟอร์ม:
  • ภาษา
  • คอมไพเลอร์
  • ห้องสมุด
  • เครื่องมือ
  • สภาพแวดล้อมรันไทม์ (JVM)

2. คุณสมบัติใหม่ใน Java 8

ไม่ว่าในกรณีใด Java 8 จะเป็นเวอร์ชันหลัก เราสามารถพูดได้ว่ามันใช้เวลานานมากเนื่องจากการปรับใช้คุณสมบัติที่นักพัฒนา Java ทุกคนกำลังมองหา ในส่วนนี้เราจะครอบคลุมส่วนใหญ่

2.1. Lambdas และอินเทอร์เฟซเชิงฟังก์ชัน

Lambdas (หรือที่รู้จักกันในชื่อวิธีการส่วนตัวหรือแบบไม่ระบุชื่อ) คือการเปลี่ยนแปลงภาษาที่ใหญ่ที่สุดและเป็นที่คาดหวังมากที่สุดใน Java 8 ทั้งหมด ซึ่งช่วยให้เราระบุฟังก์ชันการทำงานเป็นอาร์กิวเมนต์ของ method ได้ (โดยการประกาศฟังก์ชันที่อยู่รอบๆ) หรือระบุโค้ดเป็นข้อมูล : แนวคิดที่นักพัฒนาฟังก์ชั่นทุกคนคุ้นเคย การเขียนโปรแกรม _ หลายภาษาบนแพลตฟอร์ม JVM (Groovy, Scala , ... ) มี lambdas ตั้งแต่วันแรก แต่นักพัฒนา Java ไม่มีทางเลือกอื่นนอกจากต้องเป็นตัวแทนของ lambdas ผ่านคลาสที่ไม่ระบุชื่อ การถกเถียงเรื่องการออกแบบแลมบ์ดาใช้เวลาและความพยายามอย่างมากต่อสาธารณชน แต่ในที่สุดก็พบการประนีประนอมซึ่งนำไปสู่การเกิดการออกแบบที่กระชับใหม่ ในรูปแบบที่ง่ายที่สุด แลมบ์ดาสามารถแสดงเป็นรายการพารามิเตอร์ที่คั่นด้วยเครื่องหมายจุลภาค สัญลักษณ์ –>และเนื้อหา ตัวอย่างเช่น:
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) )
โปรดทราบว่าประเภทของอาร์กิวเมนต์eถูกกำหนดโดยคอมไพเลอร์ นอกจากนี้ คุณยังระบุประเภทของพารามิเตอร์ได้อย่างชัดเจนโดยใส่พารามิเตอร์ไว้ในวงเล็บ ตัวอย่างเช่น:
Arrays.asList( "a", "b", "d" ).forEach( ( String e ) -> System.out.println( e ) );
ในกรณีที่ตัวแลมบ์ดามีความซับซ้อนมากขึ้น ก็สามารถใช้วงเล็บปีกกาได้ คล้ายกับคำจำกัดความฟังก์ชันทั่วไปใน Java ตัวอย่างเช่น:
Arrays.asList( "a", "b", "d" ).forEach( e -< {
    System.out.print( e );
    System.out.print( e );
} );
แลมบ์ดาสามารถอ้างถึงสมาชิกคลาสและตัวแปรท้องถิ่น (โดยปริยายทำให้การโทรมีผลไม่ว่าfinalฟิลด์นั้นจะเข้าถึงหรือไม่ก็ตาม) ตัวอย่างเช่น ข้อมูลโค้ด 2 รายการนี้เทียบเท่ากัน:
String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
    ( String e ) -> System.out.print( e + separator ) );
และ:
final String separator = ",";
Arrays.asList( "a", "b", "d" ).forEach(
    ( String e ) -> System.out.print( e + separator ) );
Lambdas สามารถคืนค่าได้ ประเภทการส่งคืนจะถูกกำหนดโดยคอมไพเลอร์ ไม่จำเป็นต้องมี การประกาศreturnหากเนื้อความของแลมบ์ดาประกอบด้วยบรรทัดเดียว ข้อมูลโค้ดทั้งสองด้านล่างนี้เทียบเท่ากัน:
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> e1.compareTo( e2 ) );
และ:
Arrays.asList( "a", "b", "d" ).sort( ( e1, e2 ) -> {
    int result = e1.compareTo( e2 );
    return result;
} );
นักพัฒนาภาษาคิดมานานแล้วว่าจะทำให้ฟังก์ชันที่มีอยู่เป็นมิตรกับแลมบ์ดาได้อย่างไร เป็นผลให้แนวคิดของอินเทอร์เฟซการทำงานเกิดขึ้น อินเทอร์เฟซการทำงานคืออินเทอร์เฟซที่มีวิธีเดียวเท่านั้น ด้วยเหตุนี้จึงสามารถแปลงเป็นนิพจน์แลมบ์ดาโดยปริยายได้ java.lang.Runnableและjava.util.concurrent.Callableสองตัวอย่างที่ดีของอินเทอร์เฟซการทำงาน ในทางปฏิบัติ อินเทอร์เฟซการทำงานมีความเปราะบางมาก หากมีใครเพิ่มวิธีอื่นแม้แต่วิธีเดียวในการกำหนดอินเทอร์เฟซ ก็จะใช้งานไม่ได้อีกต่อไป และกระบวนการคอมไพล์จะไม่สมบูรณ์ เพื่อหลีกเลี่ยงความเปราะบางนี้และกำหนดจุดประสงค์ของอินเทอร์เฟซอย่างชัดเจนว่าใช้งานได้ จึงได้เพิ่มคำอธิบายประกอบพิเศษใน Java 8 @FunctionalInterface(อินเทอร์เฟซที่มีอยู่ทั้งหมดในไลบรารี Java ได้รับคำอธิบายประกอบ @FunctionalInterface) ลองดูคำจำกัดความง่ายๆ ของอินเทอร์เฟซการทำงาน:
@FunctionalInterface
public interface Functional {
    void method();
}
มีสิ่งหนึ่งที่ต้องจำไว้: วิธีการเริ่มต้นและวิธีการแบบคงที่ไม่ละเมิดหลักการของอินเทอร์เฟซการทำงานและสามารถประกาศได้:
@FunctionalInterface
public interface FunctionalDefaultMethods {
    void method();

    default void defaultMethod() {
    }
}
Lambdas เป็นคุณสมบัติที่ได้รับความนิยมมากที่สุดของ Java 8 พวกเขามีศักยภาพทั้งหมดในการดึงดูดนักพัฒนาให้มาที่แพลตฟอร์มที่ยอดเยี่ยมนี้มากขึ้น และให้การสนับสนุนอย่างชาญฉลาดสำหรับคุณสมบัติต่างๆ ใน ​​Java ล้วนๆ สำหรับข้อมูลโดยละเอียดเพิ่มเติม โปรดดูเอกสารอย่างเป็นทางการ

2.2. อินเทอร์เฟซเริ่มต้นและวิธีการแบบคงที่

Java 8 ขยายคำจำกัดความของอินเทอร์เฟซด้วยสองแนวคิดใหม่: วิธีการเริ่มต้นและวิธีคงที่ วิธีการเริ่มต้นทำให้อินเทอร์เฟซค่อนข้างคล้ายกับลักษณะ แต่มีจุดประสงค์ที่แตกต่างกันเล็กน้อย ช่วยให้คุณสามารถเพิ่มวิธีการใหม่ให้กับอินเทอร์เฟซที่มีอยู่ได้โดยไม่ทำลายความเข้ากันได้แบบย้อนหลังสำหรับอินเทอร์เฟซเวอร์ชันที่เขียนไว้ก่อนหน้านี้ ความแตกต่างระหว่างวิธีเริ่มต้นและวิธีนามธรรมคือต้องใช้วิธีนามธรรมในขณะที่วิธีเริ่มต้นไม่ได้เป็นเช่นนั้น แต่ละอินเทอร์เฟซจะต้องจัดเตรียมสิ่งที่เรียกว่าการใช้งานเริ่มต้นแทน และผู้สืบทอดทั้งหมดจะได้รับตามค่าเริ่มต้น (โดยมีความสามารถในการแทนที่การใช้งานเริ่มต้นนี้ หากจำเป็น) ลองดูตัวอย่างด้านล่าง
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";
    }
}
อินเทอร์เฟซDefaulableประกาศวิธีการเริ่มต้นnotRequired()โดยใช้คำสำคัญdefaultเป็นส่วนหนึ่งของคำจำกัดความของวิธีการ หนึ่งในคลาส , DefaultableImplใช้อินเทอร์เฟซนี้โดยปล่อยให้วิธีการเริ่มต้นเหมือนเดิม คลาสอื่น , OverridableImplแทนที่การใช้งานเริ่มต้นและจัดเตรียมคลาสของตัวเอง คุณสมบัติที่น่าสนใจอีกประการหนึ่งที่นำมาใช้ใน Java 8 ก็คืออินเทอร์เฟซสามารถประกาศ (และเสนอการใช้งาน) วิธีการคงที่ได้ นี่คือตัวอย่าง:
private interface DefaulableFactory {
    // Interfaces now allow static methods
    static Defaulable create( Supplier<Defaulable> supplier ) {
        return supplier.get();
    }
}
โค้ดชิ้นเล็กๆ รวมวิธีการเริ่มต้นและวิธีการแบบคงที่จากตัวอย่างด้านบน:
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() );
}
ผลลัพธ์คอนโซลของโปรแกรมนี้มีลักษณะดังนี้:
Default implementation
Overridden implementation
การใช้วิธีการเริ่มต้นใน JVM นั้นมีประสิทธิภาพมาก และการเรียกใช้เมธอดได้รับการสนับสนุนโดยคำสั่ง bytecode วิธีการเริ่มต้นอนุญาตให้อินเทอร์เฟซ Java ที่มีอยู่พัฒนาโดยไม่ทำลายกระบวนการคอมไพล์ ตัวอย่างที่ดีคือวิธีการต่างๆ มากมายที่เพิ่มเข้าไปในอินเทอร์เฟซjava.util.Collection: stream(), parallelStream(), forEach(), removeIf(), ... แม้ว่าจะมีประสิทธิภาพ แต่วิธีการเริ่มต้นควรใช้ด้วยความระมัดระวัง ก่อนที่จะประกาศวิธีการเริ่มต้น คุณควรคิดให้รอบคอบก่อนว่าสิ่งนี้จำเป็นจริงๆ หรือไม่ เนื่องจากสิ่งนี้สามารถนำไปสู่ เพื่อรวบรวมความคลุมเครือและข้อผิดพลาดในลำดับชั้นที่ซับซ้อน สำหรับข้อมูลโดยละเอียดเพิ่มเติม โปรดดูที่เอกสารประกอบ

2.3. วิธีการอ้างอิง

วิธีการอ้างอิงใช้ไวยากรณ์ที่มีประโยชน์เพื่ออ้างอิงวิธีการที่มีอยู่หรือตัวสร้างของคลาสหรืออ็อบเจ็กต์ Java (อินสแตนซ์) เมื่อใช้ร่วมกับนิพจน์แลมบ์ดา วิธีการอ้างอิงจะทำให้โครงสร้างภาษามีขนาดกะทัดรัดและกระชับ ทำให้เป็นแบบตามเทมเพลต ด้านล่างนี้คือคลาสCarที่เป็นตัวอย่างของคำจำกัดความของวิธีการต่างๆ เรามาเน้นวิธีการอ้างอิงสี่ประเภทที่รองรับ:
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() );
    }
}
วิธีอ้างอิงวิธีแรกคือการอ้างอิงถึงตัวสร้างที่มีไวยากรณ์หรือClass::newทางเลือกอื่นสำหรับยาชื่อสามัญ Class< T >::newโปรดทราบว่าตัวสร้างไม่มีข้อโต้แย้ง
final Car car = Car.create( Car::new );
final List<Car> cars = Arrays.asList( car );
Class::static_methodตัวเลือกที่สองคือการอ้างอิงถึงวิธีการแบบสแต ติก ที่มีไวยากรณ์ โปรดทราบว่าวิธีการนี้รับพารามิเตอร์ประเภทเดียวCarเท่านั้น
cars.forEach( Car::collide );
ประเภทที่สามคือการอ้างอิงถึงวิธีการของอินสแตนซ์ของวัตถุที่กำหนดเองในประเภทใดประเภทหนึ่งที่มีClass::methodไวยากรณ์ โปรดทราบว่าวิธีการนี้ไม่ยอมรับข้อโต้แย้ง
cars.forEach( Car::repair );
และประเภทสุดท้ายที่สี่คือการอ้างอิงถึงวิธีการของอินสแตนซ์ของคลาสเฉพาะที่มีinstance::methodไวยากรณ์ Carโปรดทราบว่าวิธีการ นี้ ยอมรับพารามิเตอร์ประเภทเดียวเท่านั้น
final Car police = Car.create( Car::new );
cars.forEach( police::follow );
การรันตัวอย่างทั้งหมดเหล่านี้ในขณะที่โปรแกรม Java สร้างเอาต์พุตคอนโซลต่อไปนี้ (การอ้างอิงคลาสCarอาจแตกต่างกัน):
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
สำหรับข้อมูลโดยละเอียดเพิ่มเติมและรายละเอียดเกี่ยวกับวิธีการอ้างอิง โปรด ดูเอกสารอย่างเป็นทางการ

2.4. คำอธิบายประกอบที่ซ้ำกัน

เนื่องจาก Java 5 เปิดตัวการรองรับคำอธิบายประกอบคุณลักษณะนี้จึงได้รับความนิยมอย่างมากและใช้กันอย่างแพร่หลาย อย่างไรก็ตาม ข้อจำกัดประการหนึ่งของการใช้คำอธิบายประกอบคือข้อเท็จจริงที่ว่าคำอธิบายประกอบเดียวกันไม่สามารถประกาศมากกว่าหนึ่งครั้งในที่เดียวกันได้ Java 8 ฝ่าฝืนกฎนี้และแนะนำคำอธิบายประกอบที่ซ้ำกัน ซึ่งช่วยให้สามารถทำซ้ำคำอธิบายประกอบเดียวกันได้หลายครั้งในตำแหน่งที่ประกาศไว้ คำอธิบายประกอบที่ซ้ำกันควรใส่คำอธิบายประกอบด้วยตนเองโดยใช้คำอธิบาย@Repeatableประกอบ อันที่จริง นี่ไม่ใช่การเปลี่ยนแปลงภาษามากนักเนื่องจากเป็นเคล็ดลับของคอมไพเลอร์ ในขณะที่เทคนิคยังคงเหมือนเดิม ลองดูตัวอย่างง่ายๆ:
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() );
        }
    }
}
ดังที่เราเห็นแล้วว่าคลาสนั้นFilterถูกใส่คำอธิบายประกอบด้วย @Repeatable( Filters. class) Filtersเป็นเพียงเจ้าของคำอธิบายประกอบFilterแต่คอมไพเลอร์ Java พยายามซ่อนการแสดงตนจากนักพัฒนา ดังนั้นอินเทอร์เฟซจึงFilterableมีคำอธิบายประกอบFilterที่ถูกประกาศสองครั้ง (โดยไม่กล่าวถึงFilters) Reflection API ยังมีวิธีการใหม่getAnnotationsByType()ในการส่งคืนคำอธิบายประกอบที่ซ้ำกันบางประเภท (โปรดจำไว้ว่า Filterable. class.getAnnotation( Filters. class) จะส่งคืนอินสแตนซ์ที่คอมไพเลอร์ฉีดFilters) ผลลัพธ์ของโปรแกรมจะมีลักษณะดังนี้:
filter1
filter2
สำหรับข้อมูลโดยละเอียดเพิ่มเติม โปรดดูเอกสารอย่างเป็นทางการ

2.5. ปรับปรุงการอนุมานประเภท

คอมไพเลอร์ Java 8 ได้รับการปรับปรุงการอนุมานหลายประเภท ในหลายกรณี คอมไพลเลอร์สามารถกำหนดพารามิเตอร์ประเภทที่ชัดเจนได้ ดังนั้นจึงทำให้โค้ดสะอาดขึ้น ลองดูตัวอย่างหนึ่ง:
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;
    }
}
และนี่คือการใช้งานกับ type 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() );
    }
}
พารามิเตอร์ type Value.defaultValue()ถูกกำหนดโดยอัตโนมัติ และไม่จำเป็นต้องระบุอย่างชัดเจน ใน Java 7 ตัวอย่างเดียวกันนี้จะไม่คอมไพล์และจะต้องเขียนใหม่เป็น <NOBR>Value.<String>defaultValue()</NOBR>

2.6. การสนับสนุนคำอธิบายประกอบแบบขยาย

Java 8 ขยายบริบทที่สามารถใช้คำอธิบายประกอบได้ ทุกวันนี้ เกือบทุกอย่างสามารถมีคำอธิบายประกอบได้: ตัวแปรท้องถิ่น, ประเภททั่วไป, ซูเปอร์คลาสและอินเทอร์เฟซที่นำไปใช้ แม้กระทั่งข้อยกเว้นของเมธอด ตัวอย่างบางส่วนแสดงไว้ด้านล่าง:
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และElementType.TYPE_PARAMETERองค์ประกอบใหม่สองประเภทเพื่ออธิบายบริบทคำอธิบายประกอบที่เกี่ยวข้อง Annotation Processing APIยังได้รับการเปลี่ยนแปลงเล็กน้อยเพื่อรับรู้ประเภทคำอธิบายประกอบใหม่ใน Java

3. คุณสมบัติใหม่ในคอมไพเลอร์ Java

3.1. ชื่อพารามิเตอร์

ตลอดเวลาที่ผ่านมา นักพัฒนา Java ได้คิดค้นวิธีการต่างๆ มากมายในการจัดเก็บชื่อพารามิเตอร์ของเมธอดใน Java bytecodeเพื่อให้สามารถใช้งานได้ในขณะรันไทม์ (เช่นไลบรารี Paranamer ) ในที่สุด Java 8 จะสร้างฟังก์ชันที่ยากลำบากนี้ในภาษา (โดยใช้ Reflection API และ method Parameter.getName()) และ bytecode (โดยใช้อาร์กิวเมนต์คอมไพเลอร์ใหม่ 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() );
        }
    }
}
หากคุณคอมไพล์คลาสนี้โดยไม่ใช้อาร์กิวเมนต์–parametersแล้วรันโปรแกรม คุณจะเห็นสิ่งนี้:
Parameter: arg0
เมื่อพารามิเตอร์–parametersส่งผ่านไปยังคอมไพเลอร์ ผลลัพธ์ของโปรแกรมจะแตกต่างออกไป (ชื่อจริงของพารามิเตอร์จะแสดง):
Parameter: args
สำหรับผู้ใช้ Maven ขั้นสูงสามารถเพิ่มอาร์กิวเมนต์ –parameters ลงในการคอมไพล์ได้โดยใช้ส่วน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>
เพื่อตรวจสอบความพร้อมของ ชื่อ พารามิเตอร์มีisNamePresent()วิธีที่สะดวกในคลาสParameter

4. เครื่องมือ Java ใหม่

Java 8 มาพร้อมกับชุดเครื่องมือบรรทัดคำสั่งใหม่ ในส่วนนี้เราจะดูสิ่งที่น่าสนใจที่สุด

4.1. เครื่องยนต์ Nashorn: jjs

jjsเป็นเอ็นจิ้น Nashorn แบบสแตนด์อโลนที่ใช้บรรทัดคำสั่ง ใช้รายการไฟล์ซอร์สโค้ด JavaScript และเรียกใช้งาน ตัวอย่างเช่น เรามาสร้าง ไฟล์ func.jsที่มีเนื้อหาดังต่อไปนี้:
function f() {
     return 1;
};

print( f() + 1 );
หากต้องการเรียกใช้ไฟล์นี้ ให้ส่งผ่านเป็นอาร์กิวเมนต์ไปที่jjs :
jjs func.js
เอาต์พุตคอนโซลจะเป็นดังนี้:
2
สำหรับรายละเอียดเพิ่มเติมโปรดดูเอกสารประกอบ

4.2. ตัววิเคราะห์การพึ่งพาคลาส: jdeps

jdepsเป็นเครื่องมือบรรทัดคำสั่งที่ยอดเยี่ยมจริงๆ มันแสดงการพึ่งพาระดับแพ็คเกจหรือคลาสสำหรับคลาส Java โดยยอมรับ ไฟล์ .classโฟลเดอร์ หรือไฟล์ JARเป็นอินพุต ตามค่าเริ่มต้นjdepsส่งออกการพึ่งพาไปยังเอาต์พุตมาตรฐาน (คอนโซล) ตามตัวอย่าง ลองดูรายงานการขึ้นต่อกันของไลบรารีSpring Framework ยอดนิยม เพื่อให้ตัวอย่างกระชับ ลองดูที่การขึ้นต่อกันของไฟล์ JAR org.springframework.core-3.0.5.RELEASE.jarเท่านั้น
jdeps org.springframework.core-3.0.5.RELEASE.jar
คำสั่งนี้ให้ผลลัพธ์ค่อนข้างมาก ดังนั้นเราจะวิเคราะห์ผลลัพธ์เพียงบางส่วนเท่านั้น การขึ้นต่อกันจะถูกจัดกลุ่มตามแพ็คเกจ หากไม่มีการอ้างอิงไม่พบ จะปรากฏ ขึ้น
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
สำหรับข้อมูลโดยละเอียดเพิ่มเติม โปรดดูเอกสารอย่างเป็นทางการ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION