Java從8到21的語言新特性

Narcissu5發表於2024-03-16

try-with-resource可以使用既有的變數

// java 9 之前
try (InputStream is = Files.newInputStream(Paths.get("1111"))) {
    // do something
}

// java 9 之後可以這樣了
InputStream is = Files.newInputStream(Paths.get("1111"));
try (is) {
    // do something
}

鑽石運算子擴充套件

現在鑽石運算子可以和匿名類一起使用:

FooClass<Integer> fc = new FooClass<>(1) {
};

FooClass<? extends Integer> fc0 = new FooClass<>(1) {

};

FooClass<?> fc1 = new FooClass<>(1) {
};

介面私有方法

介面可以包含私有方法,主要用於防止預設方法過長:

interface InterfaceWithPrivateMethods {

    private static String staticPrivate() {
        return "static private";
    }

    private String instancePrivate() {
        return "instance private";
    }

    default void check() {
        String result = staticPrivate();
        InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {

        };
        result = pvt.instancePrivate();
    }
}

型別推斷var

型別推斷僅可用於區域性變數和lambda表示式中:

var x = 1;

switch表示式

在此之前:

// 之前
boolean isTodayHoliday;
switch (day) {
    case "MONDAY":
    case "TUESDAY":
    case "WEDNESDAY":
    case "THURSDAY":
    case "FRIDAY":
        isTodayHoliday = false;
        break;
    case "SATURDAY":
    case "SUNDAY":
        isTodayHoliday = true;
        break;
    default:
        throw new IllegalArgumentException("What's a " + day);
}

// 從14開始
boolean isTodayHoliday = switch (day) {
    case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> false;
    case "SATURDAY", "SUNDAY" -> true;
    default -> throw new IllegalArgumentException("What's a " + day);
};

// 從17開始
static record Human (String name, int age, String profession) {}

public String checkObject(Object obj) {
    return switch (obj) {
        case Human h -> "Name: %s, age: %s and profession: %s".formatted(h.name(), h.age(), h.profession());
        case Circle c -> "This is a circle";
        case Shape s -> "It is just a shape";
        case null -> "It is null";
        default -> "It is an object";
    };
}

public String checkShape(Shape shape) {
    return switch (shape) {
        case Triangle t && (t.getNumberOfSides() != 3) -> "This is a weird triangle";
        case Circle c && (c.getNumberOfSides() != 0) -> "This is a weird circle";
        default -> "Just a normal shape";
    };
}

字元塊

String multiline = """
    A quick brown fox jumps over a lazy dog; \
    the lazy dog howls loudly.""";

字串模板

String interpolationUsingSTRProcessor(String feelsLike, String temperature, String unit) {
    return STR
      . "Today's weather is \{ feelsLike }, with a temperature of \{ temperature } degrees \{ unit }" ;
}

// 或者字串塊
String interpolationOfJSONBlock(String feelsLike, String temperature, String unit) {
    return STR
      . """
      {
        "feelsLike": "\{ feelsLike }",
        "temperature": "\{ temperature }",
        "unit": "\{ unit }"
      }
      """ ;
}

也可以帶格式化的:

String interpolationOfJSONBlockWithFMT(String feelsLike, float temperature, String unit) {
    return FMT
      . """
      {
        "feelsLike": "%1s\{ feelsLike }",
        "temperature": "%2.2f\{ temperature }",
        "unit": "%1s\{ unit }"
      }
      """ ;
}

參見baeldung的說明。

模式匹配 instanceof

可以在instanceof判斷的同時宣告新的變數了:

if (obj instanceof String str) {
    int len = str.length();

}

Records

public record User(int id, String password) { };

Sealed Classes (JEP 360)

只允許特定的類繼承,配合模式匹配會很好用,即可以確定匹配到所有已知的型別:

public abstract sealed class Person permits Employee, Manager {
}

public final class Employee extends Person {
}

public non-sealed class Manager extends Person {
}

參考:

  1. New Features in Java 14
  2. New Features in Java 17

相關文章