Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我可以在Java中使用嵌套泛型吗?_Java_Generics - Fatal编程技术网

我可以在Java中使用嵌套泛型吗?

我可以在Java中使用嵌套泛型吗?,java,generics,Java,Generics,我试着做一些事情,比如: public class MyClass <A, B, C <A, B> > { ... } 公共类MyClass{ ... } 但Eclipse突出显示了“B”,并表示“意外的、预期的扩展”。有什么好处?不允许嵌套泛型吗?您不必像那样声明嵌套类型。简单地 class MyClass<A, B, C> {} 类MyClass{} 当您创建MyClass时,您可以执行以下操作 MyClass<List<Str

我试着做一些事情,比如:


public class MyClass <A, B, C <A, B> > {
  ...
}

公共类MyClass{
...
}

但Eclipse突出显示了“B”,并表示“意外的、预期的扩展”。有什么好处?不允许嵌套泛型吗?

您不必像那样声明嵌套类型。简单地

class MyClass<A, B, C> {}
类MyClass{}
当您创建MyClass时,您可以执行以下操作

MyClass<List<String>, Set<Date>, Map<Integer, Long>> instance;
MyClass实例;

这是因为您没有将
C
定义为一个本身带有两个类型参数的类型。
试着这样做:

public class MyClass <A, B, C extends Map<A, B>> {
    // This compiles
}
公共类MyClass{
//这就编译了
}

我猜您希望MyClass是具有类型参数a、B和C的泛型类。此外,您希望C是具有类型参数a和B的泛型类

这样我就可以写作了

  • MyClass>
  • MyClass>
    但不是
  • MyClass

  • 那么我认为您不能这样做。

    如果您的模板参数不共享类层次结构,您可以使用接口

    例如:

    interface IConverter<TFrom, TTo>
    {
        TTo convert(TFrom from);
    }
    
    class IntToStringConverter implements IConverter<Integer, String>
    {
        public String convert(Integer from)
        {
            return "This is a string: " + from.toString();
        }
    }
    
    class ConverterUser<TConverter extends IConverter<TFrom, TTo>, TFrom, TTo>
    {
        public ConverterUser()
        {
        }
    
        private List<TConverter> _converter2;
    
        private TConverter _converter;
    
        public void replaceConverter(TConverter converter)
        {
            _converter = converter;
        }
    
        public TTo convert(TFrom from)
        {
            return _converter.convert(from);
        }
    }
    
    class Test
    {
        public static void main(String[] args)
        {
            ConverterUser<IntToStringConverter, Integer, String> converterUser =
                new ConverterUser<IntToStringConverter, Integer, String>();
    
            converterUser.replaceConverter(new IntToStringConverter());
    
            System.out.println(converterUser.convert(328));
        }
    }
    
    接口IConverter
    {
    TTo转换(TFrom from);
    }
    类IntToStringConverter实现IConverter
    {
    公共字符串转换(整数从)
    {
    return“这是一个字符串:+from.toString();
    }
    }
    类转换器
    {
    公共转换器()
    {
    }
    私有列表转换器2;
    专用t转换器(u转换器),;
    公用变频器(TConverter变频器)
    {
    _转换器=转换器;
    }
    公共TTo转换(从中转换)
    {
    返回_converter.convert(从);
    }
    }
    课堂测试
    {
    公共静态void main(字符串[]args)
    {
    转换器转换器转换器转换器=
    新转换器();
    replaceConverter(新的IntToStringConverter());
    System.out.println(converterUser.convert(328));
    }
    }
    
    这在Java中是不可能的。请参见语言定义的一节以及。我最近(在某处)看到有人提到Java不能做到这一点,但Scala可以做到。本标准S4.4对此进行了确认

    以下代码编译成功也多少证实了这一点

    class MyClass [A, B, C [A, B]] {
    }
    
    用java编译得到了以下答案

    MyClass.java:1: > expected
    class MyClass <A, B, C<A, B>> {
                          ^
    MyClass.java:1: <identifier> expected
    class MyClass <A, B, C<A, B>> {
                            ^
    MyClass.java:1: ';' expected
    class MyClass <A, B, C<A, B>> {
                               ^
    MyClass.java:2: reached end of file while parsing
    }
     ^
    4 errors
    
    MyClass.java:1:>应为
    类MyClass{
    ^
    java:1:应为
    类MyClass{
    ^
    java:1:“;”应为
    类MyClass{
    ^
    java:2:解析时到达文件末尾
    }
    ^
    4个错误
    

    不过,我想有一个更简单的方法来解决你的问题,因为这有点不寻常。

    这是允许的。如果你愿意,可以展示你的实际类…@Doug:鉴于你对下面答案的回答,我怀疑这里有更深层次的困惑。也许你可以发布更多的示例代码,展示你对
    MyC客户的期望lass
    应该能够使用它,这可能会让你的问题更清楚。但是如果C可以是几个没有公共父类的类中的一个呢?@Doug:如果C没有公共的超类型,那么你怎么知道它需要参数化呢?如果你只是说拥有相同的父类,那么这实际上是没有必要的ry如果
    扩展
    约束在接口上,因为Java支持多接口继承。@Daniel,对了,我认为这里的答案是我应该在第三个模板槽中使用接口。如果我试图使用内置Java类,那么我需要使用他们实现的接口和我的类E这也是实现。如果这还不够好,没有涵盖我需要的所有功能,那么内置类也无法提供,因此两者都不适合使用。我认为这就是解决这种情况的答案。我接受这个答案,但实际上这是因为这个答案和Daniel的注释相结合。我尝试了这个,但后来当我试图用C=newc()之类的东西实例化C时,编译器抱怨道;@Doug:C是一个类型参数。它不可实例化。如果你退一步,更广泛地解释你要解决的问题,也许有人能指出更好的解决方法。所以我真正的问题是,一般来说,类型参数是不可实例化的。那么使用C作为模板参数的子类呢?这是许可证吗TET?这正是我想要的。嗯,我怀疑可能是这样,这很不幸,因为它会导致大量的代码重复。实际上,我正在努力思考一个用例。那么什么代码会被复制呢?嗯,我正在研究一种与map具有相同接口的东西,有时作为子类与map一起使用,但是也可以将用户定义的类用作子类,在这种情况下,通过赋予get、put等新的含义来扩展功能。@Doug:
    Map
    不是类,而是接口。(如果您指的是
    java.util.Map
    ,至少不是这样)使用接口的全部意义在于它们定义了类型上的一组有效操作。如果您的泛型类型不共享公共接口,那么您的代码应该如何操作它们?@Daniel,对,我想这就是答案,我应该在第三个模板槽中使用一个接口。如果我试图使用内置Java类,然后我需要使用它们实现的接口,我的类也要实现。如果这还不够好,没有涵盖我需要的所有功能,那么内置类也不能提供它,所以两者都不适合使用。我想这就是问题的答案。我忘了“扩展”Dan,我喜欢这个答案,但我认为最好的答案应该是这个和当前accep的结合