Core Java

New Features in Java 10

Java 10, released in 2018, introduced several noteworthy features. Let us delve into the new Java 10 features.

1. Local Variable Type Inference

Java 10 introduced a new feature known as “Local Variable Type Inference” (var keyword), allowing developers to declare local variables without explicitly specifying their data types. Local variable type inference improves code readability and reduces boilerplate code without sacrificing the benefits of static typing. Consider the following example:

public class LocalVariableTypeInferenceExample {
  public static void main(String[] args) {
    var message = "Hello, World!"; // Compiler infers type as String
    var numbers = List.of(1, 2, 3, 4, 5); // Compiler infers type as List<Integer>

    // Other examples...
  }
}

In the above example, the type of the variable message is inferred as String, and the type of numbers is inferred as List<Integer>.

While using var is convenient, it’s essential to ensure that the code remains clear and maintainable. Avoid excessive use in cases where specifying the type explicitly enhances readability.

2. Unmodifiable Collections

In Java 10, the Collections framework introduced a convenient way to create unmodifiable collections using the of factory methods. These methods allow you to create compact and immutable collections with ease. Using unmodifiable collections ensures that your data remains constant throughout the program execution, providing safety in multi-threaded environments and preventing accidental modifications. Let’s look at a few examples:

// List
List<String> immutableList = List.copyOf("Apple", "Banana", "Orange");

// Set
Set<Integer> immutableSet = Set.copyOf(1, 2, 3, 4, 5);

// Map
Map<String, Integer> immutableMap = Map.copyOf("One", 1, "Two", 2, "Three", 3);

In the above examples, the resulting collections (immutableList, immutableSet, and immutableMap) are unmodifiable, meaning any attempt to modify them (add, remove, or update elements) will result in an UnsupportedOperationException.

Keep in mind that while the collections themselves are unmodifiable, the elements within them may still be mutable. If you need a fully immutable solution, ensure that the elements themselves are immutable or use custom logic to handle immutability.

3. Optional.orElseThrow()

In Java, the Optional class provides the orElseThrow method, which is used to retrieve the value from the Optional or throw a specific exception if the Optional is empty. Using orElseThrow can make your code more expressive and help you handle cases where the absence of a value is considered exceptional. Consider the following example:

import java.util.Optional;

public class OptionalOrElseThrowExample {
  public static void main(String[] args) {
    Optional<String> optionalValue = Optional.of("Hello, World!");
    // Using orElseThrow
    String result = optionalValue.orElseThrow(() -> new IllegalStateException("Value is not present"));

    System.out.println("Result: " + result);
  }
}

In this example, the orElseThrow method is used to retrieve the value from optionalValue. If the optional is empty, it throws an IllegalStateException with the specified error message.

When using orElseThrow, make sure to provide a meaningful exception to help with debugging and understanding the context of the error.

4. Performance Improvements

Java 10 introduced several performance improvements to enhance the overall efficiency and responsiveness of Java applications. These improvements address various aspects of the Java Virtual Machine (JVM) and the standard library.

  • Application Class-Data Sharing (CDS): Java 10 enhances the Class-Data Sharing (CDS) feature, which allows classes to be preprocessed into a shared archive file. This shared archive can be memory-mapped at runtime, reducing startup time and memory footprint. To enable CDS, you can use the -XX:UseAppCDS option.
    // Create
    $ java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=helloworld.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar
    
    // Use
    $ java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=helloworld.jsa -cp helloworld.jar HelloWorld
    
  • Parallel Full GC for G1: Java 10 introduces a parallel full garbage collector for the G1 (Garbage-First) garbage collector. This aims to improve the performance of G1 by parallelizing the full garbage collection phase, leading to more efficient garbage collection in scenarios where G1 is used as the garbage collector.
  • Thread-Local Handshakes: Thread-Local Handshakes are introduced to improve the efficiency of VM operations involving all threads. It allows the VM to reach a safe point with minimal impact on application threads, reducing the pause time during certain operations like garbage collection.

5. Container Awareness

Java 10 introduces features and improvements to make Java applications more container-aware, addressing specific challenges and providing better support for running Java applications within containerized environments such as Docker.

  • Application Class-Data Sharing (CDS) for Docker: Java 10 enhances the Class-Data Sharing (CDS) feature with optimizations for container environments. This allows classes to be preprocessed into a shared archive file that is optimized for running within Docker containers, improving startup time and memory efficiency in containerized deployments.
  • Improved Docker Container Support: Java 10 includes enhancements to better detect and support container environments. It introduces new system properties, such as jdk.attach.allowAttachSelf, to improve the interaction between Java applications and container orchestrators. These improvements aim to make Java applications behave more predictably and efficiently when deployed in containerized environments.
  • Memory-Pressure Detection for cgroups: Java 10 introduces better detection of memory pressure when running in a container with control groups (cgroups). This allows Java applications to adapt their behavior based on available container resources, leading to more efficient resource utilization and improved application stability in containerized deployments.

6. Root Certificates

Java includes a default set of root certificates that play a crucial role in securing communication over SSL/TLS protocols. Root certificates are part of the public key infrastructure (PKI) and are used to verify the authenticity of digital certificates issued by trusted Certificate Authorities (CAs).

  • Default Root Certificates: Java maintains a truststore containing a set of root certificates from well-known CAs. These certificates are used to establish a chain of trust during SSL/TLS handshakes, ensuring that the server’s certificate is valid and issued by a trusted authority.
  • Updating Root Certificates: While Java versions may not explicitly mention updates to root certificates in release notes, it’s essential to keep your Java runtime environment up to date. Regularly updating your Java installation ensures that it includes the latest security patches, which may include updates to root certificates to reflect changes in the CA landscape.
  • Customizing Truststores: In certain scenarios, you may need to customize the truststore used by your Java application. This could involve adding or removing specific root certificates based on your security requirements. Ensure proper precautions are taken when modifying truststores to maintain a secure and trustworthy connection environment.

7. Time-Based Release Versioning

Java transitioned to a time-based release model starting with Java 9. This approach involves regular feature releases every six months, providing developers with a more predictable and frequent update cycle.

7.1 Key Features of Time-Based Releases

  • Regular Updates: New Java feature releases are scheduled every six months, ensuring a steady stream of updates with the latest enhancements, bug fixes, and features.
  • Predictable Cadence: The predictable release cadence allows developers to plan and adopt new features more easily. This agile approach aligns with modern development practices and facilitates a more responsive development process.
  • Continuous Improvement: The time-based model promotes continuous improvement by providing a regular flow of updates. Developers can take advantage of the latest language enhancements, performance improvements, and security patches.

Developers are encouraged to stay current with the latest Java releases to benefit from the ongoing improvements and innovations. The time-based release model aims to make it easier for developers to adopt new features without the need to wait for extended periods between major releases.

8. Conclusion

In Java 10, several notable features and improvements have been introduced, contributing to enhanced developer productivity and application performance. The adoption of Local Variable Type Inference (var) brings conciseness to code by allowing developers to declare local variables without explicitly specifying the data type. Unmodifiable Collections offer a safer and more secure approach to handling collections, ensuring immutability and preventing unintended modifications. The addition of Optional*.orElseThrow() provides a streamlined way to handle optional values, allowing developers to retrieve a value or throw a specified exception if the optional is empty. Java 10 also focuses on Performance Improvements, addressing efficiency and responsiveness in areas such as garbage collection and application startup times. Container Awareness enhancements cater to the evolving landscape of containerized environments, optimizing Java applications for better compatibility and resource utilization. Root Certificates play a crucial role in securing SSL/TLS communications, and while specifics may vary, Java often includes a default set for establishing trust. Lastly, the transition to Time-Based Release Versioning signifies a shift towards a more predictable and frequent update cycle, allowing developers to stay current with the latest features and improvements on time. Together, these features and advancements in Java 10 reflect a commitment to innovation, security, and adaptability in the ever-evolving realm of software development.

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button