Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to define static fields for type parameter in java generics

I want to define a time interface like that:

public interface TimeInterface<T>
{
    static T ZERO;
    static T INFINITY;
    // some other methods...
}

Is this possible, or how to do that to avoid errors?

Thanks in advance!

like image 385
Frank Avatar asked Jul 07 '15 08:07

Frank


2 Answers

From the javadoc directly:

We cannot declare static fields whose types are type parameters

A class's static field is a class-level variable shared by all non-static objects of the class. Hence, static fields of type parameters are not allowed. Consider the following class:

public class MobileDevice<T> {
    private static T os;

    // ...
}

If static fields of type parameters were allowed, then the following code would be confused:

MobileDevice<Smartphone> phone = new MobileDevice<>();
MobileDevice<Pager> pager = new MobileDevice<>();
MobileDevice<TabletPC> pc = new MobileDevice<>();

Because the static field os is shared by phone, pager, and pc, what is the actual type of os? It cannot be Smartphone, Pager, and TabletPC at the same time. You cannot, therefore, create static fields of type parameters.

like image 197
Razib Avatar answered Oct 07 '22 01:10

Razib


The only static thing that can contain type-parameters is the static method, which must define it's own type-parameters. Something like:

static <T> void staticGenericMethod(T param) { .. }

In your case, the type-parameter has a class scope, it's instance-bound and has nothing to do with the static members of the class.

So, you should either remove the static keywords for ZERO and INFINITY or introduce static methods that return ZERO and INFINITY. For example:

public interface TimeInterface<T> {
    static <X> X getZero() { 
         //implementation
    }
    static <X> X getInfinity() {

    }
}

Note that the X type-parameters are valid for the corresponding static method only and are not shared across the class.

The problem, however, with this approach is that there's no way to ensure that the instance type-parameter (T) is the same as the static method's type-parameter (X), which may cause serious problems when used incorrectly.

Also note that static methods are allowed in interfaces in Java8, so if you're using an order Java version, you should convert the TimeInterface to a class.

like image 21
Konstantin Yovkov Avatar answered Oct 07 '22 00:10

Konstantin Yovkov