API yang akhirnya layak diupgrade dari Java 8 untuk. Bagian 3

Apa alasan untuk bermigrasi ke versi Java yang baru? Seseorang akan melakukannya karena fitur bahasa baru seperti switch



, blok teks atau catatan . Seseorang akan membutuhkan fitur baru yang menarik seperti modul atau pengumpul sampah dengan jeda rendah . Seseorang akan melakukan ini hanya karena dengan memperbarui versi Java, program mereka akan menjadi lebih cepat dan akan memakan lebih sedikit memori . Tapi ada satu alasan lagi yang tidak kalah pentingnya. Ini adalah API baru yang memungkinkan Anda menulis lebih sedikit kode dan menghindari membuang-buang waktu mencari fungsionalitas yang diinginkan di pustaka eksternal. Dan dalam beberapa kasus, mereka akan membuat kode Anda lebih cepat.







Di dua bagian sebelumnya, kami telah membahas 10 API baru yang muncul di Java 9 dan yang lebih baru ( bagian 1 , bagian 2 ). Hari ini kita akan melihat 10 lagi.









satu. Stream.toList()





Diperkenalkan di: Java 16



Apa tugas yang paling umum digunakan Stream



di Java? Tentu saja, untuk transformasi daftar: kami memiliki daftar di mana kami perlu melakukan beberapa jenis transformasi dan mengembalikan yang baru. Anda mungkin telah melihat pola ini berkali-kali dalam proyek Anda:







List<T> targetList = sourceList
        .stream()
        //  
        .collect(Collectors.toList());
      
      





Ini bukan untuk mengatakan bahwa ini collect(Collectors.toList())



adalah konstruksi yang sangat rumit, tetapi saya masih ingin menulis lebih sedikit kode untuk operasi yang sering dilakukan. Dan di Java 16, ini menjadi mungkin dengan metode baru Stream.toList()



:







List<T> targetList = sourceList
        .stream()
        //  
        .toList();
      
      





- toList()



collect(Collectors.toList())



? ? , : toList()



, collect(Collectors.toList())



, , . (, ), collect(Collectors.toList())



toList()



.







Stream.toList()



, ! , Stream.toList()



Stream.toArray()



, , Spliterator



SIZED



. Collectors.toList()



ArrayList



, .







. : , , .. . Stream



, new ArrayList<>(sourceList)



List.copyOf(sourceList)



, :







JMH-
import org.openjdk.jmh.annotations.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class ToList {

    @Param({"10", "100", "1000"})
    private int size;

    private List<Integer> sourceList;

    @Setup
    public void setup() {
        sourceList = IntStream
                .range(0, size)
                .boxed()
                .collect(Collectors.toList());
    }

    @Benchmark
    public List<Integer> newArrayList() {
        return new ArrayList<>(sourceList);
    }

    @Benchmark
    public List<Integer> toList() {
        return sourceList.stream().toList();
    }

    @Benchmark
    public List<Integer> copyOf() {
        return List.copyOf(sourceList);
    }

    @Benchmark
    public List<Integer> collectToList() {
        return sourceList.stream().collect(Collectors.toList());
    }

    @Benchmark
    public List<Integer> collectToUnmodifiableList() {
        return sourceList.stream().collect(Collectors.toUnmodifiableList());
    }
}
      
      





OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
Intel Core i5-9500 3.00GHZ
 : -f 3 -wi 3 -w 5 -i 5 -r 5 -t 6 -jvmArgs -XX:+UseParallelGC
      
      







, Stream.toList()



collect(Collectors.toList())



, List.copyOf()



! , List.copyOf()



requireNonNull



, null



-, Stream.toList()



null



. List.copyOf()



, null



, Stream



: Spliterator



, ReferencePipeline



..







, . , filter()



:







JMH-
import org.openjdk.jmh.annotations.*;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Thread)
public class ToListFilter {

    @Param({"10", "100", "1000"})
    private int size;

    private List<Integer> sourceList;

    @Setup
    public void setup() {
        sourceList = IntStream
                .range(0, size)
                .boxed()
                .collect(Collectors.toList());
    }

    @Benchmark
    public List<Integer> toList() {
        return sourceList.stream().filter(i -> i % 2 == 0).toList();
    }

    @Benchmark
    public List<Integer> newArrayList() {
        var list = new ArrayList<Integer>();
        for (var i : sourceList) {
            if (i % 2 == 0) {
                list.add(i);
            }
        }
        return list;
    }

    @Benchmark
    public List<Integer> collectToList() {
        return sourceList.stream().filter(i -> i % 2 == 0).collect(Collectors.toList());
    }

    @Benchmark
    public List<Integer> collectToUnmodifiableList() {
        return sourceList.stream().filter(i -> i % 2 == 0).collect(Collectors.toUnmodifiableList());
    }
}
      
      





OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
Intel Core i5-9500 3.00GHZ
 : -f 3 -wi 3 -w 5 -i 5 -r 5 -t 6 -jvmArgs -XX:+UseParallelGC
      
      









! Stream.toList()



new ArrayList()



. ? , Stream.toArray()



SpinedBuffer



, , ArrayList



. , ( chunk ). SpinedBuffer



, 100 (Integer



0 99):









ArrayList



, 1.5 , , . ArrayList



add()



, SpinedBuffer



, . , , .







: Stream.toList()



, , collect(Collectors.toList())



. ( Collectors.toList()



, downstream Collector



Collector



'). , collect(Collectors.toCollection(ArrayList::new))



.









2. String



: formatted()



, stripIndent()



translateEscapes()





: Java 15



Java 15 – , :







String str = """
        ,
        !""";
      
      





:







String str = String.format("""
        ,
        %s!""", user);
      
      





, ? . , . String.formatted()



, String.format()



:







String str = """
        ,
        %s!""".formatted(user);
      
      





, , , , , -, ( ), -, .







, formatted()



:







String str = ", %s!".formatted(user);
      
      





, .









, Java 15 – String.stripIndent()



, . , hello.txt



:







    ,
    !
      
      





, stripIndent()



:







String str = Files.readString(Path.of("hello.txt")).stripIndent();
System.out.println(str);
      
      





:







,
!
      
      







, – String.translateEscapes()



. : .







, hello.txt:







,\n!
      
      





String str = Files.readString(Path.of("hello.txt")).translateEscapes();
System.out.println(str);
      
      





:







,
!
      
      







3. CharSequence.isEmpty()



, CharSequence.compare()



StringBuilder.compareTo()





: Java 15 / Java 11



, .







, Java 1.5 , , String



isEmpty()



. length()



:







if (str.length() != 0) {
    ...
}
      
      





, Java 1.6 String.isEmpty()



- :







if (!str.isEmpty()) {
    ...
}
      
      





, String



CharSequence



( ), - , (, default



- ). , StringBuilder



length()



:







if (stringBuilder.length() != 0) {
    ...
}
      
      





14 - : Java 15, isEmpty()



String



, CharSequence



:







if (!stringBuilder.isEmpty()) {
    ...
}
      
      







CharSequence



. equals()



: ? : CharSequence



String



, , .







, Java 11, , CharSequence.compare()



:







if (CharSequence.compare(charSeq1, charSeq2) == 0) {
    ...
}
      
      





compare()



, .







Java 11 StringBuilder



Comparable



, StringBuilder



compareTo()



:







if (stringBuilder1.compareTo(stringBuilder2) == 0) {
    ...
}
      
      







4. Collectors.filtering()



Collectors.flatMapping()





: Java 9



Collectors.groupingBy()



? , :







record Movie(String title, String genre, double rating) {
}
      
      





, :







Stream<Movie> allMovies = Stream.of(
    new Movie("", "", 7.385),
    new Movie("", "", 7.974),
    new Movie(" 2", "", 8.312),
    new Movie(" ", "", 8.33),
    new Movie(" ", "", 8.619),
    new Movie("", "", 8.363),
    new Movie("", "", 7.699)
);

Map<String, List<Movie>> groups = allMovies.collect(
    Collectors.groupingBy(Movie::genre));

groups.forEach((genre, movies) -> {
    System.out.println(genre + ":");
    movies.forEach(movie ->
        System.out.printf("    %s: %.2f%n", movie.title(), movie.rating()));
});
      
      





:







:
    : 8.36
:
    : 7.39
    : 7.97
     2: 8.31
:
     : 8.33
     : 8.62
:
    : 7.70
      
      





, , , , 8. ? , Stream.filter()



:







Map<String, List<Movie>> groups = allMovies
    .filter(movie -> movie.rating() > 8)
    .collect(Collectors.groupingBy(Movie::genre));
      
      





:
    : 8.36
:
     2: 8.31
:
     : 8.33
     : 8.62
      
      





: , , 8. ? : Java, Collectors.filtering()



:







Map<String, List<Movie>> groups = allMovies.collect(
    Collectors.groupingBy(Movie::genre,
        Collectors.filtering(movie -> movie.rating() > 8,
            Collectors.toList())));

groups.forEach((genre, movies) -> {
    System.out.println(genre + ":");
    if (movies.isEmpty()) {
        System.out.println("    <    8 >");
    } else {
        movies.forEach(movie ->
            System.out.printf("    %s: %.2f%n", movie.title(), movie.rating()));
    }
});
      
      





groupingBy()



, :







:
    : 8.36
:
     2: 8.31
:
     : 8.33
     : 8.62
:
    <    8 >
      
      







. :







record Movie(String title, String genre, double rating, List<String> actors) {
}
      
      





:







Stream<Movie> allMovies = Stream.of(
    new Movie("", "", 7.385,
        List.of("", "", "")),
    new Movie("", "", 7.974,
        List.of("", "", "")),
    new Movie(" 2", "", 8.312,
        List.of("", "", "", "")),
    new Movie(" ", "", 8.33,
        List.of("", "")),
    new Movie(" ", "", 8.619,
        List.of("", "", "", "")),
    new Movie("", "", 8.363,
        List.of("", "")),
    new Movie("", "", 7.699,
        List.of("", ""))
);
      
      





groupingBy()



, Set



? Collectors.mapping()



:







Map<String, Set<List<String>>> groups = allMovies.collect(
    Collectors.groupingBy(Movie::genre,
        Collectors.mapping(Movie::actors, Collectors.toSet())));
      
      





, , . ? Collectors.flatMapping()



, , Java 9:







Map<String, Set<String>> groups = allMovies.collect(
    Collectors.groupingBy(Movie::genre,
        Collectors.flatMapping(movie -> movie.actors().stream(),
            Collectors.toSet())));
      
      





! , :







:
    
    
:
    
    
    
    
    
    
    
:
    
    
    
    
    
    
:
    
    
      
      





.









5. StackWalker





: Java 9



? , ? , :







public final class MyLogger {
    public static void log(String message) {
        System.out.println(message);
    }
}
      
      





, , , , log()



. Java 8 StackTraceElement[]



, , Thread.getStackTrace()



:







public static void log(String message) {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    StackTraceElement stackTraceElement = stackTrace[2];
    String msg = stackTraceElement.getClassName() + "."
               + stackTraceElement.getMethodName() + "("
               + stackTraceElement.getFileName() + ":"
               + stackTraceElement.getLineNumber() + ") "
               + message;
    System.out.println(msg);
}
      
      





, . , ( , ), JVM Java-. , . :







@Benchmark
public String stackTrace() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    StackTraceElement stackTraceElement = stackTrace[2];
    return stackTraceElement.getClassName() + "."
         + stackTraceElement.getMethodName() + "("
         + stackTraceElement.getFileName() + ":"
         + stackTraceElement.getLineNumber() + ")";
}
      
      





OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
Intel Core i5-9500 3.00GHZ
 : -f 1 -wi 3 -w 3 -i 5 -r 5 -t 6
      
      





Benchmark          Mode  Cnt    Score   Error  Units
Stack.stackTrace   avgt    5  103,704 ? 1,123  us/op
      
      





104 ! ! ? : StackWalker



, Java 9. .







StackWalker



«» . , StackWalker



StackWalker.getInstance()



. StackWalker



. getInstance()



StackWalker



. .







, StackWalker



, :









. log()



:







public static void log(String message) {
    String msg = StackWalker
        .getInstance()
        .walk((Stream<StackFrame> frames) -> {
            StackFrame frame = frames.skip(2).findFirst().get();
            return frame.getClassName() + "."
                 + frame.getMethodName() + "("
                 + frame.getFileName() + ":"
                 + frame.getLineNumber() + ") "
                 + message;
        });
    System.out.println(msg);
}
      
      





StackWalker



:







@Benchmark
public String stackWalker() {
    return StackWalker
        .getInstance()
        .walk(frames -> {
            StackFrame frame = frames.skip(2).findFirst().get();
            return frame.getClassName() + "."
                 + frame.getMethodName() + "("
                 + frame.getFileName() + ":"
                 + frame.getLineNumber() + ")";
        });
}
      
      





OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing)
Intel Core i5-9500 3.00GHZ
 : -f 1 -wi 3 -w 3 -i 5 -r 5 -t 6
      
      





Benchmark          Mode  Cnt    Score   Error  Units
Stack.stackTrace   avgt    5  103,704 ? 1,123  us/op
Stack.stackWalker  avgt    5    2,781 ? 0,156  us/op
      
      





37 ! . , 2.8 , , .







StackWalker.walk()



Stream



, : , , -. , «», :







package org.mylogger;

public final class MyLogger {
    public enum Level {
        ERROR, WARN, INFO
    }

    public static void error(String message) {
        log(Level.ERROR, message);
    }

    public static void warn(String message) {
        log(Level.WARN, message);
    }

    public static void info(String message) {
        log(Level.INFO, message);
    }

    public static void log(Level level, String message) {
        ...
    }
}
      
      





frames.skip(2)



, log()



, error()



, warn()



, log()



, . – Stream.dropWhile()



:







public static void log(Level level, String message) {
    String msg = StackWalker
        .getInstance()
        .walk((Stream<StackFrame> frames) -> {
            StackFrame frame = frames
                .dropWhile(f -> f.getClassName().startsWith("org.mylogger"))
                .findFirst()
                .get();
            return level + " "
                 + frame.getClassName() + "."
                 + frame.getMethodName() + "("
                 + frame.getFileName() + ":"
                 + frame.getLineNumber() + ") "
                 + message;
        });
    System.out.println(msg);
}
      
      







StackWalker



?







, Java 9 . , classpath. – , . , org.example.mylib.internal



, , :







package org.example.mylib.internal;

public final class Handler {
    public static void handle() {
        ...
    }
}
      
      





Handler



, . , , ? , StackWalker.getCallerClass()



, :







package org.example.mylib.internal;

public final class Handler {
    public static void handle() {
        if (!StackWalker
            .getInstance(Option.RETAIN_CLASS_REFERENCE)
            .getCallerClass()
            .getPackageName()
            .startsWith("org.example.mylib.")) {
            throw new RuntimeException("Security error");
        }
        ...
    }
}
      
      





RETAIN_CLASS_REFERENCE



, Class . , Stream.walk()



, getCallerClass()



.









6. System.Logger





: Java 9



, API , Java 9. API : System.Logger



, System.LoggerFinder



System.Logger.Level



.







System.Logger



:







public final class Main {
    private static final Logger LOGGER = System.getLogger("");

    public static void main(String[] args)  {
        LOGGER.log(Level.ERROR, "Critical error!");
    }
}
      
      





:







. 17, 2021 6:24:57 PM org.example.Main main
SEVERE: Critical error!
      
      





System.Logger



– , , . , : , SLF4J – , Logback. Log4j API – Log4j Core. , System.Logger



java.util.logging



, java.logging



.







SLF4J , , Log4j java.util.logging



. Log4j API SLF4J java.util.logging



. System.Logger



: , . java.util.logging



, - . , Log4j, :







<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.14.1</version> <!--       -->
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.14.1</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-jpl</artifactId>
    <version>2.14.1</version>
    <scope>runtime</scope>
</dependency>
      
      





: , log4j-jpl



classpath, . Java ServiceLoader



LoggerFinder



Log4jSystemLoggerFinder



Log4j:







18:24:57.941 [main] ERROR  - Critical error!
      
      





java.logging



JRE/JDK, ( java.util.logging



).







, System.Logger



SLF4J/Logback . – , SLF4J . GitHub . Log4j – .







System.Logger



:







LOGGER.log(Level.INFO, "Information");
LOGGER.log(Level.DEBUG, "Sum of {} and {} is {}:", 2, 3, 2+3);
LOGGER.log(Level.TRACE, () -> "Lazy message");
LOGGER.log(Level.ERROR, "Log exception", new Exception());
      
      







7. Lookup.defineHiddenClass()





: Java 15



MethodHandles.Lookup.defineClass()



, , . , : , , ( ). , . Java 15 , .







Lookup.defineHiddenClass()



. Unsafe.defineAnonymousClass()



, , . Unsafe.defineAnonymousClass()



Java 15 deprecated for removal.







:







  • . .
  • . , ( Class.forName()



    , ClassLoader.loadClass()



    , ClassLoader.findLoadedClass()



    ..). - < ->/<suffix>



    (, org.example.Temp/0x0000000800cb8000



    ).
  • , , , Class



    ( , , ClassOption.STRONG



    defineHiddenClass()



    ).
  • , -XX:+UnlockDiagnosticVMOptions -XX:+ShowHiddenFrames



    .


, , . :







jshell> Runnable runnable = () -> {}
runnable ==> $Lambda$26/0x0000000800c0aa00@443b7951

jshell> runnable.getClass().isHidden()
$2 ==> true
      
      







« ». int



'. javac, ByteBuddy.







- :







byte[] bytes = new ByteBuddy()
        .subclass(Object.class)
        .name("org.example.Temp")
        .defineMethod("sum", int.class, Modifier.PUBLIC)
        .withParameters(int.class, int.class)
        .intercept(new Implementation.Simple(
                MethodVariableAccess.INTEGER.loadFrom(1),
                MethodVariableAccess.INTEGER.loadFrom(2),
                Addition.INTEGER,
                MethodReturn.INTEGER))
        .make()
        .getBytes();
      
      





, -:







package org.example;
public class Temp {
    public int sum(int x, int y) {
        return x + y;
    }
}
      
      





, - , - :







Lookup lookup = MethodHandles
        .lookup()
        .defineHiddenClass(bytes, false);

//     MethodHandle  reflection
Object obj = lookup
        .findConstructor(lookup.lookupClass(), MethodType.methodType(void.class))
        .invoke();

MethodHandle sumHandle = lookup.findVirtual(lookup.lookupClass(), "sum",
        MethodType.methodType(int.class, int.class, int.class));

//   sum.   5
System.out.println(sumHandle.invoke(obj, 3, 2));
      
      





.









, , . :







Lookup lookup1 = MethodHandles.lookup().defineHiddenClass(bytes, false);
Lookup lookup2 = MethodHandles.lookup().defineHiddenClass(bytes, false);
Lookup lookup3 = MethodHandles.lookup().defineHiddenClass(bytes, false);
System.out.println(lookup1.lookupClass()); // class org.example.Temp/0x0000000800cb4000
System.out.println(lookup2.lookupClass()); // class org.example.Temp/0x0000000800cb4400
System.out.println(lookup3.lookupClass()); // class org.example.Temp/0x0000000800cb4800
      
      







8. Math





: Java 9 / Java 15



, , Java, :







int x = ...
int y = ...
long z = x * y;
      
      





Java, : int



int



, , z



long



, . long



:







long z = (long) x * y;
      
      





, - . -, , , . -, , , . , . :







  int     long   
      
      





Java 9 . Math.multiplyFull()



:







long z = Math.multiplyFull(x, y);
      
      







Java , , Java 8 Math



:







  • int toIntExact(long value)



  • int incrementExact(int a)



  • long incrementExact(long a)



  • int decrementExact(int a)



  • long decrementExact(long a)



  • int negateExact(int a)



  • long negateExact(long a)



  • int addExact(int x, int y)



  • long addExact(long x, long y)



  • int subtractExact(int x, int y)



  • long subtractExact(long x, long y)



  • int multiplyExact(int x, int y)



  • long multiplyExact(long x, long y)





, , – , - . ? , . , , , :







jshell> Math.abs(Integer.MIN_VALUE)
$1 ==> -2147483648
      
      





, – ? , , 2147483648 int



, . , Math.absExact()



, Java 15:







jshell> Math.absExact(Integer.MIN_VALUE)
|  Exception java.lang.ArithmeticException: Overflow to represent absolute value of Integer.MIN_VALUE
|        at Math.absExact (Math.java:1392)
|        at (#1:1)

jshell> Math.absExact(Long.MIN_VALUE)
|  Exception java.lang.ArithmeticException: Overflow to represent absolute value of Long.MIN_VALUE
|        at Math.absExact (Math.java:1438)
|        at (#2:1)
      
      







, , -11 3? ? :







jshell> -11 / 3
$1 ==> -3

jshell> -11 % 3
$2 ==> -2
      
      





, -11 = 3 * (-3) - 2



. , , Python, :







>>> -11 / 3
-4
>>> -11 % 3
1
      
      





- : -11 = 3 * (-4) + 1



. , : . Java , Python – . , Java -? Java 9 Math.floorDiv()



Math.floorMod()



:







jshell> Math.floorDiv(-11, 3)
$1 ==> -4

jshell> Math.floorMod(-11, 3)
$2 ==> 1
      
      







Java 9 Math.fma(float, float, float)



Math.fma(double, double, double)



, , a * b + c



, , :







jshell> Math.fma(2.99, 5.91, 7.1)
$1 ==> 24.7709

jshell> 2.99 * 5.91 + 7.1
$2 ==> 24.770900000000005
      
      







9. java.io.Serial





: Java 14



Java? , , Java-. :







public class Point {
    private static final long serialVersionUID = 1L;

    public int x;
    public int y;
}
      
      





Point



, :







var point = new Point();
point.x = 1;
point.y = 2;

var baos = new ByteArrayOutputStream();
try (var oos = new ObjectOutputStream(baos)) {
    oos.writeObject(point);
}
byte[] bytes = baos.toByteArray();
      
      







. , ? , Serializable



! ( serialVersionUID



, .)







:







public class Point implements Serializable {
    private static final long serialVersionUID = 1;

    public int x;
    public int y;
}
      
      





– : Serializable



, serialVersionUID



, .. , Java 14 Serial



.







, :







public class Point implements Serializable {
    @Serial
    private static final long serialVersionUID = 1;
    ...
}
      
      





, , :







public class Point {
    @Serial // Annotated member is not a part of the serialization mechanism
    private static final long serialVersionUID = 1;
    ...
}
      
      





:







public class Point implements Serializable {
    @Serial // Annotated member is not a part of the serialization mechanism
    private static final int serialVersionUID = 1;
    ...
}
      
      





, : serialVersionUID



, serialPersistentFields



, writeObject()



, readObject()



..







, IntelliJ IDEA. JDK 16 -Xlint:serial



. , javac



:







> javac -Xlint:serial Point.java
Point.java:6: warning: [serial] serialVersionUID must be of type long in class Point
    private static final int serialVersionUID = 1;
                             ^
      
      





, Java 17.









10. Objects



: checkIndex()



, checkFromIndexSize()



, checkFromToIndex()





: Java 9 / Java 16



.







, , , , . :







private static void getAt(int index, int length) {
    if (index < 0) {
        throw new IllegalArgumentException("index < 0");
    }
    if (index >= length) {
        throw new IllegalArgumentException("index >= length");
    }
    ...
}
      
      





, , :







public final class PreconditionUtils {
    public static void checkIndex(int index, int length) {
        if (index < 0) {
            throw new IllegalArgumentException("index < 0");
        }
        if (index >= length) {
            throw new IllegalArgumentException("index >= length");
        }
    }
}
      
      







Java 9 , Objects



.







Objects.checkIndex()



, [0, length)



:







jshell> Objects.checkIndex(-3, 10)
|  Exception java.lang.IndexOutOfBoundsException: Index -3 out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckIndex (Preconditions.java:70)
|        at Preconditions.checkIndex (Preconditions.java:248)
|        at Objects.checkIndex (Objects.java:372)
|        at (#1:1)

jshell> Objects.checkIndex(10, 10)
|  Exception java.lang.IndexOutOfBoundsException: Index 10 out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckIndex (Preconditions.java:70)
|        at Preconditions.checkIndex (Preconditions.java:248)
|        at Objects.checkIndex (Objects.java:372)
|        at (#2:1)
      
      







Objects.checkFromIndexSize()



, [fromIndex, fromIndex + size)



[0, length)



:







jshell> Objects.checkFromIndexSize(3, 8, 10)
|  Exception java.lang.IndexOutOfBoundsException: Range [3, 3 + 8) out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckFromIndexSize (Preconditions.java:82)
|        at Preconditions.checkFromIndexSize (Preconditions.java:343)
|        at Objects.checkFromIndexSize (Objects.java:424)
|        at (#3:1)

jshell> Objects.checkFromIndexSize(-2, 8, 10)
|  Exception java.lang.IndexOutOfBoundsException: Range [-2, -2 + 8) out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckFromIndexSize (Preconditions.java:82)
|        at Preconditions.checkFromIndexSize (Preconditions.java:343)
|        at Objects.checkFromIndexSize (Objects.java:424)
|        at (#4:1)

jshell> Objects.checkFromIndexSize(3, -4, 10)
|  Exception java.lang.IndexOutOfBoundsException: Range [3, 3 + -4) out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckFromIndexSize (Preconditions.java:82)
|        at Preconditions.checkFromIndexSize (Preconditions.java:343)
|        at Objects.checkFromIndexSize (Objects.java:424)
|        at (#5:1)
      
      







, Objects.checkFromToIndex()



, [fromIndex, toIndex)



[0, length)



:







jshell> Objects.checkFromToIndex(3, 11, 10)
|  Exception java.lang.IndexOutOfBoundsException: Range [3, 11) out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckFromToIndex (Preconditions.java:76)
|        at Preconditions.checkFromToIndex (Preconditions.java:295)
|        at Objects.checkFromToIndex (Objects.java:398)
|        at (#6:1)

jshell> Objects.checkFromToIndex(-4, 8, 10)
|  Exception java.lang.IndexOutOfBoundsException: Range [-4, 8) out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckFromToIndex (Preconditions.java:76)
|        at Preconditions.checkFromToIndex (Preconditions.java:295)
|        at Objects.checkFromToIndex (Objects.java:398)
|        at (#7:1)

jshell> Objects.checkFromToIndex(6, 4, 10)
|  Exception java.lang.IndexOutOfBoundsException: Range [6, 4) out of bounds for length 10
|        at Preconditions.outOfBounds (Preconditions.java:64)
|        at Preconditions.outOfBoundsCheckFromToIndex (Preconditions.java:76)
|        at Preconditions.checkFromToIndex (Preconditions.java:295)
|        at Objects.checkFromToIndex (Objects.java:398)
|        at (#8:1)
      
      







, Java 16 long



:













10 API, Java 16, 9- . , Java. , Java , , (1, 2, 3, 4, 5, 6, 7, 8). Java 8 , .







...








All Articles