Skip to content

koher/Variance4J

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Variance4J

Variance4J provides the declaration-site variance annotations for Java like in C#.

Variance4J

How to Use

  1. Write @In and @Out in your code.
  2. Compile your code with Variance4J.

javac

javac -cp path/to/variance4j.jar Foo.java 

Eclipse

  1. Check Enable project specific settings in Properties > Java Compiler > Annotation Processing.
  2. Ensure Enable annotation processing is checked in Properties > Java Compiler > Annotation Processing.
  3. Check Enable project specific settings in Properties > Java Compiler > Annotation Processing > Factory Path.
  4. Add variance4j.jar to Properties > Java Compiler > Annotation Processing > Factory Path.
  5. Add variance4j.jar to Properties > Java Build Path > Libraries.

Achieved and Not Achieved

Achieved

It can report the errors at compile time if the return type or the parameter types of the methods are illegal.

interface Foo<@Out T> {
    void bar(T t); // Error

    void baz(Consumer<? super T> consumer); // OK
}

Not Achieved

It cannot eliminate Wildcards: ? extends and ? super. They are still necessary to realize variances in Java even if you use @In and @Out.

Foo<Cat> cat = ...;
Foo<Animal> animal = car; // Error
Foo<Cat> cat = ...;
Foo<? extends Animal> animal = car; // OK

For What?

It is difficult to use Wildcards correctly. For example, the following code has a problem.

interface Foo {
    Comparator<Integer> getComparator();
}

It is impossible to declare interface Bar extends Foo with Comparator<Number> getComparator() with the Foo above. The better one is the below.

interface Foo {
    Comparator<? super Integer> getComparator();
}

With @In and @Out, we never wonder which to use ? super or ? extends. The following simple rule is useful to decide which Wildcard to apply.

  • If declared as @In, use ? super.
  • If declared as @Out, use ? extends.
  • If declared without @In nor @Out, neither ? super nor ? extends is necessary.
/* Declaration-site */
// Contravariant for T, Covariant for R
interface Function<@In T, @Out R> {
        R apply(T t);
}
/* Use-site */
// Variables
Function<? super String, ? extends Number> function = ...;

// Parameter Types
void foo(Function<? super String, ? extends Number>) { ... }

// Return types
Function<? super String, ? extends Number> bar() { ... }

If Variance4J provided just the annotations, @In and @Out, it would be hard to declare types of methods legally. Variance4J provides the annotation processor to check the types so that programmers never declare illegal methods with @In and/or @Out.

Requirements

  • Java 8

License

The MIT License.

References

About

Declaration-site variance annotations like C# for Java.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages