Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics enforcing compatible wildcards

Tags:

java

generics

I've these classes.

class RedSocket {} class GreenSocket {} class RedWire {} class GreenWire {} 

I've a class which uses 2 generic types

public class Connection<W, S> {} 

where W is Wire type & S is Socket type.

I'm trying to enforce compile time check to ensure that socket & wire have the same color.

I tried doing this:

public class Connection<W extends Wire & Color, S extends Socket & Color> {}  interface Color {}  interface Red extends Color {} interface Green extends Color {}  interface Socket {} interface Wire {}  class RedSocket implements Socket, Red {} class GreenSocket implements Socket, Green {} class RedWire implements Wire,  Red {} class GreenWire implements Wire, Green {} 

But this doesn't really ensure that the Color used is same for both generic types and still lets me do this:

public class Connection<W extends Wire & Color, S extends Socket & Color> {     public static void main(String[] args) {         new Connection<RedWire, GreenSocket>();         new Connection<GreenWire, RedSocket>();     } } 

(Why this happens has been explained brilliantly by Radiodef here)

How can I enforce compile time check to ensure that socket & wire have the same color?

like image 764
mindreader Avatar asked Aug 27 '15 08:08

mindreader


People also ask

What is wildcard in generics in Java?

In the Java programming language, the wildcard ? is a special kind of type argument that controls the type safety of the use of generic (parameterized) types. It can be used in variable declarations and instantiations as well as in method definitions, but not in the definition of a generic type.

Why do we use wildcards in Java generics?

Wildcards in Java are basically the question marks which we use in generic programming, it basically represents the unknown type. We use Java Wildcard widely in situations such as in a type of parameter, local variable, or field and also as a return type.

What is <? Super T in Java?

super T denotes an unknown type that is a supertype of T (or T itself; remember that the supertype relation is reflexive). It is the dual of the bounded wildcards we've been using, where we use ? extends T to denote an unknown type that is a subtype of T .


1 Answers

Seems that it's better to parameterize Socket and Wire with color:

interface Socket<C extends Color> {} interface Wire<C extends Color> {}  class RedSocket implements Socket<Red> {} class GreenSocket implements Socket<Green> {} class RedWire implements Wire<Red> {} class GreenWire implements Wire<Green> {} 

This way you can introduce one more generic parameter to the Connection:

public class Connection<C extends Color, M extends Wire<C>, Q extends Socket<C>> {...} 

And use it like this:

new Connection<Red, RedWire, RedSocket>(); // ok new Connection<Green, GreenWire, GreenSocket>(); // ok new Connection<Green, GreenWire, RedSocket>(); // error 
like image 169
Tagir Valeev Avatar answered Oct 08 '22 20:10

Tagir Valeev