使用2个通用参数简化Java类

时间:2012-02-11 23:55:59

标签: java generics

我尝试创建这个类:

public class Class1<T extends Class2<E>> {
    ...
    public E someFunction(T param) {
        ...
    }
    ...
}

我看到主题[博客]:Java class with 2 generic parameters,主题建议使用此解决方案:

public class Class1<T extends Class2<E extends Class3>, E extends Class3> {
    ...
    public E someFunction(T param) {
        ...
    }
    ...
}

这是有效的,但在这种情况下,我应该使用2个参数,而不是一个:

Class1<Class21<Class31>, Class31> var = ...

在此解决方案中,我复制了类'Class31'。这个任务有更简单的解决方案,使用以下代码:

Class1<Class21<Class31>> var = ...

UPDATE1:

  

你想解决什么问题?

例如,我有图像课。 图像可以是单通道(灰度图像)和多通道(3通道用于RGB,HSB等,或4通道或RGB等等+ Alpha通道)。 此外,图像可以在字节0..255或浮点(0.0,1.0)中保存RGB值,它是不同类型的图像。 所以,我想为这些图像创建类并将其构造为:

MyImage<MyChannelType3<MyColorTypeInt>>   img1 = ...
MyImage<MyChannelType3<MyColorTypeFloat>> img2 = ...
MyImage<MyChannelType1<MyColorTypeFloat>> img3 = ...

可以访问像素中的颜色:

int Red     = img1.getPixel(x, y)[0];
float Green = img2.getPixel(x, y)[0];
float Gray  = img3.getPixel(x, y);

我认为比以下更有用:

MyImage<MyChannelType3<MyColorTypeInt>>   img1 = ...
int Red = img1.getPixel(x, y).getChannel(0).getValue();

如果我将第一次返回 MyChannelType3 ,而不是 MyColorTypeInt ,然后或返回对象并请求转换它到 int float int [] float []

1 个答案:

答案 0 :(得分:2)

这种冗余在Java中是不可避免的。

说明:在Java中, type 参数就是名称所暗示的, type 的形式参数将替换为实际的类型。你需要的是更多。您需要T作为类型构造函数的参数。就像类的构造函数生成类的实例一样,类型构造函数生成类型。 List是一个类型构造函数,它给出实际类型String生成类型List<String>

将此知识应用于您的问题,您希望T是一个类型构造函数,它使类型E <: Class3生成类型T <: Class2<E>,其中<:是子类型关系。可以按如下方式声明和使用它。

class Class1<T<X extends Class3> extends Class2<X>, E extends Class3> {
    public E someFunction(T<E> param) {
        ...
    }
}

Class1<Class21, Class31> var = ...

有关该主题的进一步阅读可在Generics of a Higher Kindpdf)中找到。除此之外,您可以查看提供更高种类的Scala

根据更新进行修改:可能更好的解决方案可能是实施PixelAccessor

public class PixelAccessor<C extends YourColor> {
    public static <C extends YourColor> get(Image<? extends ChannelType<? extends C>> image) {
        return new PixelAccessor<C>(image);
    }

    private final Image<? extends ChannelType<? extends C>> image;

    private PixelAccessor(Image<? extends ChannelType<? extends C>> image) {
        this.image = image;
    }

    public C getPixel(int x, int y) {
        // sadly this is unchecked, but "weak" type systems demand compromises
        @SuppressWarnings("unchecked")
        C color = (C) image.getPixel(x, y);
        return color;
    }
}
相关问题