9

I want to declare a generic class that will work on triplets - key, value and metadata.

The key and value fields are mandatory but the metadata field is optional.

class Triplet<K,V,M>{
    K key;
    V value;
    M metadata;
    //setters and getters
}

While using the above class I have to initialize it like below -

Triplet<Integer, String, String> t1 = new Triplet<>();
// Setters

But for some use cases metadata is optional. So when I use null as the 3rd type argument, the compiler gives an error -

Triplet<Integer, String, null> t2 = new Triplet<>();

How should I correctly instantiate a parameterized type that works for multiple types, where one of the type arguments specified at the use-site is optional?

deduper
  • 1,944
  • 9
  • 22
Rahul Vedpathak
  • 1,346
  • 3
  • 16
  • 30

3 Answers3

9

You can use Void e.g.

Triplet<Integer, String, Void> t2 = new Triplet<>();
Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
5

I would argue that if you determine that the third parameter is not present (as intended by using null), then it's no longer a triplet, but a pair. Just keep things simple and use a Pair class instead.

M A
  • 71,713
  • 13
  • 134
  • 174
5

Java does not support "optional" or gradual typing. You can try creating a subclass that defaults metadata to null, i.e. NoMetadataTriple<K,V>, or give Void for M instead as mentioned in the other answer.

The Void "type" cannot be instantiated. It's basically void (the output parameter) as a Class.

Hulk
  • 6,399
  • 1
  • 30
  • 52