Java 9 Anonymous Inner Classes Improvement and SafeVarargs Annotation

Last updated on Dec 25 2022
Prabhas Ramanathan

Java 9 introduced a new feature that allows us to use diamond operator with anonymous classes. Using the diamond with anonymous classes was not allowed in Java 7.
In Java 9, as long as the inferred type is denotable, we can use the diamond operator when we create an anonymous inner class.
Data types that can be written in Java program like int, String etc are called denotable types. Java 9 compiler is enough smart and now can infer type.
Note: This feature is included to Java 9, to add type inference in anonymous inner classes.
Let’s see an example, in which we are using diamond operator with inner class without specifying type.

Table of Contents

Java 9 Anonymous Inner Classes Example

1. abstract class ABCD<T>{ 
2. abstract T show(T a, T b); 
3. } 
4. public class TypeInferExample { 
5. public static void main(String[] args) { 
6. ABCD<String> a = new ABCD<>() { // diamond operator is empty, compiler infer type 
7. String show(String a, String b) { 
8. return a+b; 
9. } 
10. }; 
11. String result = a.show("Java","9"); 
12. System.out.println(result); 
13. } 
14. }

Output:
Java9
Although we can specifying type in diamond operator explicitly and compiler does not produce any error message. See, the following example, type is specified explicitly.

Java 9 Anonymous Inner Classes Example

1. abstract class ABCD<T>{ 
2. abstract T show(T a, T b); 
3. } 
4. public class TypeInferExample { 
5. public static void main(String[] args) { 
6. ABCD<String> a = new ABCD<String>() { // diamond operator is not empty 
7. String show(String a, String b) { 
8. return a+b; 
9. } 
10. }; 
11. String result = a.show("Java","9"); 
12. System.out.println(result); 
13. } 
14. }

And we get the same result.
Output:
Java9
What happens? If we compile the following code using Java 8.

Anonymous Inner Class Example

1. abstract class ABCD<T>{ 
2. abstract T show(T a, T b); 
3. } 
4. public class TypeInferExample { 
5. public static void main(String[] args) { 
6. ABCD<String> a = new ABCD<>() { // diamond operator is empty 
7. String show(String a, String b) { 
8. return a+b; 
9. } 
10. }; 
11. String result = a.show("Java","9"); 
12. System.out.println(result); 
13. } 
14. }

Java 8 compiler throws compile time error because it can’t infer type. The error message looks like the below.
Output:
TypeInferExample.java:7: error: cannot infer type arguments for ABCD<T>
ABCD<String> a = new ABCD<>() {
^
reason: cannot use ‘<>’ with anonymous inner classes
where T is a type-variable:
T extends Object declared in class ABCD
1 error

Java 9 @SafeVarargs Annotation

java 72

 

It is an annotation which applies on a method or constructor that takes varargs parameters. It is used to ensure that the method does not perform unsafe operations on its varargs parameters.
It was included in Java7 and can only be applied on
• Final methods
• Static methods
• Constructors

From Java 9, it can also be used with private instance methods.
Note: The @SafeVarargs annotation can be applied only to methods that cannot be overridden. Applying to the other methods will throw a compile time error.
Let’s see some examples, in first example, we are not using @SafeVarargs annotation and compiling code . See, what happens?

Java 9 @SafeVarargs Annotation Example

1. import java.util.ArrayList; 
2. import java.util.List; 
3. public class SafeVar{ 
4. private void display(List<String>... products) { // Not using @SaveVarargs 
5. for (List<String> product : products) { 
6. System.out.println(product); 
7. } 
8. } 
9. public static void main(String[] args) { 
10. SafeVar p = new SafeVar(); 
11. List<String> list = new ArrayList<String>(); 
12. list.add("Laptop"); 
13. list.add("Tablet"); 
14. p.display(list); 
15. } 
16. }

It produces warning messages at compile time, but compiles without errors.
Output:
At compile time:
Note: SafeVar.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
At runtime:
[Laptop, Tablet]
This is a compiler generated warning regarding unsafe varargs type.
To avoid it, we should use @SaveVarargs notation to the method, as we did in the following example.

Java 9 @SafeVarargs Annotation Example

1. import java.util.ArrayList; 
2. import java.util.List; 
3. public class SafeVar{ 
4. // Applying @SaveVarargs annotation 
5. @SafeVarargs 
6. private void display(List<String>... products) { // Not using @SaveVarargs 
7. for (List<String> product : products) { 
8. System.out.println(product); 
9. } 
10. } 
11. public static void main(String[] args) { 
12. SafeVar p = new SafeVar(); 
13. List<String> list = new ArrayList<String>(); 
14. list.add("Laptop"); 
15. list.add("Tablet"); 
16. p.display(list); 
17. } 
18. }

Now, compiler does not produce warning message, code compiles and runs successfully.
Output:
[Laptop, Tablet]
Note: To apply @SaveVarargs annotation on private instance methods, compile code using Java 9 or higher versions only.
What happens? If we compile the following code by using older versions of Java.

Java @SafeVarargs Annotation Example

1. import java.util.ArrayList; 
2. import java.util.List; 
3. public class SafeVar{ 
4. @SafeVarargs 
5. private void display(List<String>... products) { 
6. for (List<String> product : products) { 
7. System.out.println(product); 
8. } 
9. } 
10. public static void main(String[] args) { 
11. SafeVar v = new SafeVar(); 
12. List<String> list = new ArrayList<String>(); 
13. list.add("Laptop"); 
14. list.add("Tablet"); 
15. v.display(list); 
16. } 
17. }

Output:
SafeVar.java:6: error: Invalid SafeVarargs annotation. Instance method display(List<String>…) is not final.
private void display(List<String>… products) {
^
Note: SafeVar.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

Java 9 Private Interface Methods

In Java 9, we can create private methods inside an interface. Interface allows us to declare private methods that help to share common code between non-abstract methods.
Before Java 9, creating private methods inside an interface cause a compile time error. The following example is compiled using Java 8 compiler and throws a compile time error.

Java 9 Private Interface Methods Example

1. interface Sayable{ 
2. default void say() { 
3. saySomething(); 
4. } 
5. // Private method inside interface 
6. private void saySomething() { 
7. System.out.println("Hello... I'm private method"); 
8. } 
9. } 
10. public class PrivateInterface implements Sayable { 
11. public static void main(String[] args) { 
12. Sayable s = new PrivateInterface(); 
13. s.say(); 
14. } 
15. }

Output:
PrivateInterface.java:6: error: modifier private not allowed here
Note: To implement private interface methods, compile source code using Java 9 or higher versions only.
Now, lets execute the following code by using Java 9. See the output, it executes fine.

Java 9 Private Interface Methods Example

1. interface Sayable{ 
2. default void say() { 
3. saySomething(); 
4. } 
5. // Private method inside interface 
6. private void saySomething() { 
7. System.out.println("Hello... I'm private method"); 
8. } 
9. } 
10. public class PrivateInterface implements Sayable { 
11. public static void main(String[] args) { 
12. Sayable s = new PrivateInterface(); 
13. s.say(); 
14. } 
15. }

Output:
Hello… I’m private method
Such like, we can also create private static methods inside an interface. See, the following example.

Java 9 Private Static Methods Example

1. interface Sayable{ 
2. default void say() { 
3. saySomething(); // Calling private method 
4. sayPolitely(); // Calling private static method 
5. } 
6. // Private method inside interface 
7. private void saySomething() { 
8. System.out.println("Hello... I'm private method"); 
9. } 
10. // Private static method inside interface 
11. private static void sayPolitely() { 
12. System.out.println("I'm private static method"); 
13. } 
14. } 
15. public class PrivateInterface implements Sayable { 
16. public static void main(String[] args) { 
17. Sayable s = new PrivateInterface(); 
18. s.say(); 
19. } 
20. }

Output:
Hello… I’m private method
I’m private static method

 

Java 9 Try With Resource Enhancement

Java introduced try-with-resource feature in Java 7 that helps to close resource automatically after being used.
In other words, we can say that we don’t need to close resources (file, connection, network etc) explicitly, try-with-resource close that automatically by using AutoClosable interface.
In Java 7, try-with-resources has a limitation that requires resource to declare locally within its block.

Example Java 7 Resource Declared within resource block

1. import java.io.FileNotFoundException; 
2. import java.io.FileOutputStream; 
3. public class FinalVariable { 
4. public static void main(String[] args) throws FileNotFoundException { 
5. try(FileOutputStream fileStream=new FileOutputStream("tecklearn.txt");){ 
6. String greeting = "Welcome to tecklearn."; 
7. byte b[] = greeting.getBytes(); 
8. fileStream.write(b); 
9. System.out.println("File written"); 
10. }catch(Exception e) { 
11. System.out.println(e); 
12. } 
13. } 
14. }

This code executes fine with Java 7 and even with Java 9 because Java maintains it’s legacy.
But the below program would not work with Java 7 because we can’t put resource declared outside the try-with-resource.

Java 7 Resource declared outside the resource block

If we do like the following code in Java 7, compiler generates an error message.

1. import java.io.FileNotFoundException; 
2. import java.io.FileOutputStream; 
3. public class FinalVariable { 
4. public static void main(String[] args) throws FileNotFoundException { 
5. FileOutputStream fileStream=new FileOutputStream("tecklearn.txt"); 
6. try(fileStream){ 
7. String greeting = "Welcome to tecklearn."; 
8. byte b[] = greeting.getBytes(); 
9. fileStream.write(b); 
10. System.out.println("File written"); 
11. }catch(Exception e) { 
12. System.out.println(e); 
13. } 
14. } 
15. }

Output:
error: <identifier> expected
try(fileStream){
To deal with this error, try-with-resource is improved in Java 9 and now we can use reference of the resource that is not declared locally.
In this case, if we execute the above program using Java 9 compiler, it will execute nicely without any compile error.

Java 9 try-with-resource Example

1. import java.io.FileNotFoundException; 
2. import java.io.FileOutputStream; 
3. public class FinalVariable { 
4. public static void main(String[] args) throws FileNotFoundException { 
5. FileOutputStream fileStream=new FileOutputStream("tecklearn.txt"); 
6. try(fileStream){ 
7. String greeting = "Welcome to tecklearn."; 
8. byte b[] = greeting.getBytes(); 
9. fileStream.write(b); 
10. System.out.println("File written"); 
11. }catch(Exception e) { 
12. System.out.println(e); 
13. } 
14. } 
15. }

Output:
File written

So, this brings us to the end of blog. This Tecklearn ‘Java 9 Anonymous Inner Classes Improvement and SafeVarargs Annotation’ blog helps you with commonly asked questions if you are looking out for a job in Java Programming. If you wish to learn Java and build a career Java Programming domain, then check out our interactive, Java and JEE Training, that comes with 24*7 support to guide you throughout your learning period. Please find the link for course details:

Java and JEE Training

Java and JEE Training

About the Course

Java and JEE Certification Training is designed by professionals as per the industrial requirements and demands. This training encompasses comprehensive knowledge on basic and advanced concepts of core Java & J2EE along with popular frameworks like Hibernate, Spring & SOA. In this course, you will gain expertise in concepts like Java Array, Java OOPs, Java Function, Java Loops, Java Collections, Java Thread, Java Servlet, and Web Services using industry use-cases and this will help you to become a certified Java expert.

Why Should you take Java and JEE Training?

• Java developers are in great demand in the job market. With average pay going between $90,000/- to $120,000/- depending on your experience and the employers.
• Used by more than 10 Million developers worldwide to develop applications for 15 Billion devices.
• Java is one of the most popular programming languages in the software world. Rated #1 in TIOBE Popular programming languages index (15th Consecutive Year)

What you will Learn in this Course?

Introduction to Java

• Java Fundamentals
• Introduction to Java Basics
• Features of Java
• Various components of Java language
• Benefits of Java over other programming languages
• Key Benefits of Java

Installation and IDE’s for Java Programming Language

• Installation of Java
• Setting up of Eclipse IDE
• Components of Java Program
• Editors and IDEs used for Java Programming
• Writing a Simple Java Program

Data Handling and Functions

• Data types, Operations, Compilation process, Class files, Loops, Conditions
• Using Loop Constructs
• Arrays- Single Dimensional and Multi-Dimensional
• Functions
• Functions with Arguments

OOPS in Java: Concept of Object Orientation

• Object Oriented Programming in Java
• Implement classes and objects in Java
• Create Class Constructors
• Overload Constructors
• Inheritance
• Inherit Classes and create sub-classes
• Implement abstract classes and methods
• Use static keyword
• Implement Interfaces and use it

Polymorphism, Packages and String Handling

• Concept of Static and Run time Polymorphism
• Function Overloading
• String Handling –String Class
• Java Packages

Exception Handling and Multi-Threading

• Exception handling
• Various Types of Exception Handling
• Introduction to multi-threading in Java
• Extending the thread class
• Synchronizing the thread

File Handling in Java

• Input Output Streams
• Java.io Package
• File Handling in Java

Java Collections

• Wrapper Classes and Inner Classes: Integer, Character, Boolean, Float etc
• Applet Programs: How to write UI programs with Applet, Java.lang, Java.io, Java.util
• Collections: ArrayList, Vector, HashSet, TreeSet, HashMap, HashTable

Java Database Connectivity (JDBC)

• Introduction to SQL: Connect, Insert, Update, Delete, Select
• Introduction to JDBC and Architecture of JDBC
• Insert/Update/Delete/Select Operations using JDBC
• Batch Processing Transaction
• Management: Commit and Rollback

Java Enterprise Edition – Servlets

• Introduction to J2EE
• Client Server architecture
• URL, Port Number, Request, Response
• Need for servlets
• Servlet fundamentals
• Setting up a web project in Eclipse
• Configuring and running the web app with servlets
• GET and POST request in web application with demo
• Servlet lifecycle
• Servlets Continued
• Session tracking and filter
• Forward and include Servlet request dispatchers

Java Server Pages (JSP)

• Fundamentals of Java Server Page
• Writing a code using JSP
• The architecture of JSP
• JSP Continued
• JSP elements: Scriptlets, expressions, declaration
• JSP standard actions
• JSP directives
• Introduction to JavaBeans
• ServletConfig and ServletContext
• Servlet Chaining
• Cookies Management
• Session Management

Hibernate

• Introduction to Hibernate
• Introduction to ORM
• ORM features
• Hibernate as an ORM framework
• Hibernate features
• Setting up a project with Hibernate framework
• Basic APIs needed to do CRUD operations with Hibernate
• Hibernate Architecture

POJO (Plain Old Java Object)

• POJO (Plain Old Java Object)
• Persistent Objects
• Lifecycle of Persistent Object

Spring

• Introduction to Spring
• Spring Fundamentals
• Advanced Spring

Got a question for us? Please mention it in the comments section and we will get back to you.

0 responses on "Java 9 Anonymous Inner Classes Improvement and SafeVarargs Annotation"

Leave a Message

Your email address will not be published. Required fields are marked *