Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

Java Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:


1. Overview

In this article, we'll look at the diamond operator in Java and how generics and the Collections API influenced its evolution.

2. Raw Types

Prior to Java 1.5, the Collections API supported only raw types – there was no way for type arguments to be parameterized when constructing a collection:

List cars = new ArrayList();
cars.add(new Object());
cars.add(new Integer(1));

This allowed any type to be added and led to potential casting exceptions at runtime.

3. Generics

In Java 1.5, Generics were introduced – which allowed us to parameterize the type arguments for classes, including those in the Collections API – when declaring and constructing objects:

List<String> cars = new ArrayList<String>();

At this point, we have to specify the parameterized type in the constructor, which can be somewhat unreadable:

Map<String, List<Map<String, Map<String, Integer>>>> cars 
 = new HashMap<String, List<Map<String, Map<String, Integer>>>>();

The reason for this approach is that raw types still exist for the sake of backward compatibility, so the compiler needs to differentiate between these raw types and generics:

List<String> generics = new ArrayList<String>();
List<String> raws = new ArrayList();

Even though the compiler still allows us to use raw types in the constructor, it will prompt us with a warning message:

ArrayList is a raw type. References to generic type ArrayList<E> should be parameterized

4. Diamond Operator

The diamond operator – introduced in Java 1.7 – adds type inference and reduces the verbosity in the assignments – when using generics:

List<String> cars = new ArrayList<>();

The Java 1.7 compiler's type inference feature determines the most suitable constructor declaration that matches the invocation.

Consider the following interface and class hierarchy for working with vehicles and engines:

public interface Engine { }
public class Diesel implements Engine { }
public interface Vehicle<T extends Engine> { }
public class Car<T extends Engine> implements Vehicle<T> { }

Let's create a new instance of a Car using the diamond operator:

Car<Diesel> myCar = new Car<>();

Internally, the compiler knows that Diesel implements the Engine interface and then is able to determine a suitable constructor by inferring the type.

5. Conclusion

Simply put, the diamond operator adds the type inference feature to the compiler and reduces the verbosity in the assignments introduced with generics.

Some examples of this tutorial can be found on the GitHub project, so feel free to download it and play with it.

Java bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Generic footer banner
Comments are closed on this article!