Are private parameter type applications possible in Java?

I know about Josh Bloch typeafe heterogeneous container :

<T> void container.put(Class<T>, T);
<T> T container.get(Class<T>);

I also read about the Neal Gafter "Super" typical heterogeneous container :

<T> void container.put(TypeToken<T>, T);
<T> T container.get(TypeToken<T>);

However, the following container did not slip away from me:

<T> void container.put(Foo<T>, Bar<T>);
<T> Bar<T> container.put(Foo<T>);

where Fooand Barany common reference type.

Trying to write this, you will need to do something like:

// Setting T at the class level would force some fixed
// T or at best a bounded range of types
class Container<A, B/*, T */> {

    // So we can't have this:
    // Map<A<T>, B<T>> map = new HashMap<>();

    // And must do this (at the expense of type safety):
    Map<A<?>, B<?>> map = new HashMap<>();


    <T> void container.put(A<T> a, B<T> b) {
        map.put(a, b);
    } 

    <T> B<T> container.get(A<T> a) {
        // Not sure what to do here
    }
}

and then you can do something like:

// This doesn't compile because T is not specified and thus this is not actual Java:

class FooBarContainer extends Container<Foo, Bar, T> {   
   ...
}  

FooBarContainer container = new FooBarContainer();

// Can do this:
container.put(new Foo<String>(), new Bar<String>());
Bar<String> bar = container.get( /* some Foo<String> */ );

// Cannot do this:
container.put(new Foo<Long>(), new Bar<String>());
Bar<String> bar = container.get( /* some Foo<Long> */ );

But alas, this is not legal Java.

What I see here is that class level generics are orthogonal to method level generics. This is problem? If so, is there any way to put this up in Java?

, , . ? , , , - , .

+4
1

.

, , , . , , :

class Container<A<B>> {}

"A" , , , . , "A" - , , , :

class Container<A extends Foo<B>> {}

, API:

interface Container<KeyType, ValueType>
{
   void put(KeyType k, ValueType v);
   ValueType get(KeyType k);
}

/ ( java.util.Map, ), :

interface StringContainer extends Container<String, String>
{
   void put(String k, String v);
   String get(String k);
}

interface FooBarContainer<C> extends Container<Foo<C>, Bar<C>>
{
   void put(Foo<C> k, Bar<C> v);
   Bar<C> get(Foo<C> k);
}

/ ValueType.

KeyType ValueType , :

interface VarContainer
{
   <VariantType> void put(Foo<VariantType> k, Bar<VariantType> v);
   <VariantType> Bar<VariantType> get(Foo<VariantType> k);
}

/ VarContainer:

VarContainer vc = ...
vc.put(new Foo<String>(), new Bar<String>());

vc.put(new Foo<Long>(), new Bar<Long>());

:

interface VarContainer<VariantType> extends Container<Foo<VariantType>, Bar<VariantType>>
{
   void put(Foo<VariantType> k, Bar<VariantType> v);
   Bar<VariantType> get(Foo<VariantType> k);
}

, , Foo Bar:

interface FooBarVarContainer
{
   <VariantType> void put(Foo<VariantType> k, Bar<VariantType> v);
   Bar<VariantType> get(Foo<VariantType> k);
}

Foo/Bar, put :

FooBarVarContainer vc = ...
vc.put(new Foo<String>(), new Bar<String>()); // ok
vc.put(new Foo<String>(), new Bar<Long>()); // fails to compile
Bar<Long> = vc.get(new Foo<Long>()); // ok

, ?

, , hashCode equals, , . , - , - .

+1
source

Source: https://habr.com/ru/post/1599644/


All Articles