Java generic field declaration

后端 未结 5 771
天命终不由人
天命终不由人 2021-01-11 12:01

In a class without generic types I want to declare a rather complex generic field similar to these:

public class Client {
    private Map

        
相关标签:
5条回答
  • 2021-01-11 12:33

    You can not do it directly on the field, but you can maintain your types policy by generic methods (they can exist even in non-generic class):

    @SuppressWarnings("rawtypes")
    private Map<Class, List> map;
    
    public <T extends Serializable> void put(Class<T> key, List<Consumer<? extends T>> value) {
        map.put(key, value);
    }
    
    @SuppressWarnings("unchecked")
    public <T extends Serializable> List<Consumer<? extends T>> get(Class<T> key) {
        return map.get(key);
    }
    
    0 讨论(0)
  • 2021-01-11 12:38

    You can't the way you want it done. But you can set as an Object and cast. Other hacky answers include using a List of <? extends Serializable> (but this only works for one extends) and then add() your item or an internal class that does something like:

    private class Foo<T> {
            T obj;
    }
    

    so you can access/mutate obj internally.

    0 讨论(0)
  • 2021-01-11 12:39

    You can't. Your only option is to declare the generic type parameters in your Client class declaration. If your Client class has no generic type parameters, its members can't be generic. You must use actual types in the declaration of your class members.

    0 讨论(0)
  • 2021-01-11 12:59

    You have to somewhere introduce the type-parameter, so that you can use them in the definition for your class members.

    Introducing a type-parameter can be done only on a class-level, or on a method-level. In your case, it should be on class-level:

    public class Client<T extends Serializable, S extends T> {
        private Map<Class<T>, List<Consumer<S>>> classToConsumerTry1;
    
        private Map<Class<T>, List<Consumer<S>>> classToConsumerTry2;
    }
    

    This, however, implies that for both members (classToConsumerTry1 and classToConsumerTry2), T and S are the same. If you want them to be different, the you will have to get these two values from two different classes, both of which are parameterized with separate type-parameters.

    0 讨论(0)
  • 2021-01-11 12:59

    As a note it is possible to declare a class type as a field (since google sends me here for this unrelated question...)

      Class<? extends MyInterface> myCurrentClass = MyImplementation.class;
    
    0 讨论(0)
提交回复
热议问题