0

我正在玩一个有趣的架构。人们可以制作包含 StoredObjects 的 Store。商店可以支持由接口表示的不同操作(即Get、Put、Print)。

这是它的样子,高度简化:

interface Put<Foo>{
   public void put(Foo f); 
}

class Store implements Put<Store.Obj<?>> {
    class Obj<T> {
        public T o;
    }
    @Override
    public void put(Obj<?> o) { }


}

public class Main {
        public static void main(String[] args){
                Store s = new Store();
                Store.Obj<String> o = s.new Obj<>();
                s.put(o);

        }
}

当我想实现类似的“get”方法时,问题就出现了。理想情况下,我想要一个如下所示的界面:

interface Get<Foo> {
    public <T> T get(Foo<T> f);
}

显然,这是畸形的java。是否有一些语法(或 hack)可以用来完成它的目的?实际上,我不想将常量类型指定为泛型参数,而是将可参数化类型指定为泛型参数(然后它本身将在 get 方法中参数化)。是的,这归结为 java 没有的更高种类的类型;如此疯狂 - 丑陋的黑客非常受欢迎!

由于其他设计限制而无法使用的常见解决方案:

  • 将 get/put/etc 操作移入内部Obj
  • 创建一些超类型Store.Obj<T>并指定要采用它的接口,而不是通用参数。
4

2 回答 2

0

我想我们可以从一开始就忘记更高种类的类型,并且您知道您的建议是不可能的。

这不是您可能想要的解决方案,但这是我在这个问题上最好的短板。

由于我们无法创建新的参数类型,因此我们将不得不求助于创建新的参数值。

首先,我们必须声明它Foo是一个泛型类型。事实上,Java 8 中有一种更好的类型:Supplier<T>

interface Supplier<T> {
  T get()
}

现在,假设我必须使用这种类型的值:

Supplier<String> s = () -> "Hello";
Supplier<Integer> i = () -> 42;

好吧,既然我们没有已经建立的更高种类的类型,那么我们的Get接口必须在编译时与一些泛型类型耦合:

interface Get<S, F extends Supplier<S>> {
    public S get(Supplier<S> foo);
}

显然,问题在于,Get对于每种可能的 T 类型,您都需要多个实例/值Supplier<T>,因此我们的值会爆炸式增长:

Get<String, Supplier<String>> f = Supplier::get;
Get<Integer, Supplier<Integer>> g = Supplier::get;

然后我们可以做

String m = f.get(); //yield "Hello"
Integer n = g.get(); //yields 42

供应商几乎可以包含您想要的任何内容,但我认为我们无法避免定义多个 Get 实例。

于 2015-01-30T13:03:53.050 回答
0

你需要一些方法来从你的 Obj 中取出 T。我们称之为Getter

interface Getter<O, I> {
    I get(O outer); // get the "inner" value out of the "outer" object
}

现在你可以为你的Obj类实现一个getter:

class ObjTGetter<T> implements Getter<Obj<T>, T> {
    public T get(Obj<T> o) { return o.o; }
}

现在你的Store构造函数也必须包含一个Getter参数,所以你可以使用它来实现get。然后您的 Store 类变为:

class Store<O, I> implements Put<O>, Get<O, I> {
    private Getter<O, I> getter;
    public void put(O o) { … }
    public I get(O o) { … }
}

但是到那时你也可以摆脱你的Store并直接使用getter。

于 2015-01-30T10:19:37.773 回答