2011-12-26 17 views
9

这是一种对讨论的后续问题:Java 7的钻石操作方法调用

Why doesn't the diamond operator work within a addAll() call in Java 7?

Java教程,

http://docs.oracle.com/javase/tutorial/java/generics/gentypeinference.html

注意,钻石经常用于方法调用;然而,为了更清楚起见,建议您使用钻石主要初始化一个变量,在其中声明

所以,我对第一行有点困惑。当确实钻石在方法调用中工作?

了一下如何操作的钻石作品都可以在这里找到更多的解释:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20type%20argument%20inference%20for%20constructors

而从这个,我曾尝试以下,工作正常:

给我有:

private static class Box<T>{ 
    public Box(T t){} 
} 
static void f(Box<Integer> box){} 

类似下面的调用编译罚款:

​​

的在调用上述方法调用f()中的构造函数时使用的类型参数是从构造函数的参数(即Integer)中推断出来的。

因此,这是什么时候的教程说

注意,钻石经常工作在方法意味着调用

如果没有,任何人都可以友好地提供了一个例子,其中钻石作品方法调用中的

+0

@gurung了一个错字。切不好的情况下,粘贴:( – 2011-12-26 17:02:54

回答

3

因此,这是什么时候的教程说

我想是的,虽然有几个陷阱的当谈到<>运营商的意思。

对于您的情况,Box实例化是一个非问题,因为可以使用构造函数参数轻松推断该类型。尝试更改构造函数为“不”,请参阅IntegerT并查看调用失败的方式。

class BadBox<T> { 

    private T t; 

    public BadBox(){}  

    public void setT(T t) { 
     this.t = t; 
    } 

    static void f(BadBox<Integer> box){} 

    public static void main(final String[] args) { 
     f(new BadBox<>()); //fails, should have worked ideally 
    }  
} 

同样,看一下这个类:

class Testi<R> {  
    public void doIt(Set<? extends R> sets) { 
    } 

    public static void main(final String[] args) { 
      // works since type inference is now possible 
     new Testi<CharSequence>().doIt(new HashSet<>(Arrays.asList("a"))); 

      // fails; nothing which can help with type inference 
     new Testi<CharSequence>().doIt(new HashSet<>(); 
    }  
} 

同样,在你的链接的问题(关于addAll)的问题可以简单地通过帮助了编译器一点如下解决:

List<String> list = new ArrayList<>(); 
list.add("A"); 

// works now! use only if you love diamond operator ;) 
list.addAll(new ArrayList<>(Arrays.asList(new String[0]))); 
// or the old-school way 
list.addAll(new ArrayList<String>())); 

钻石运营商也似乎打破,当谈到实现匿名类,如下所示:

final String[] strings = { "a", "b", "c" }; 
Arrays.sort(strings, new Comparator<>() { 
    @Override 
    public int compare(String o1, String o2) { 
     return 0; 
    } 
}); 

幸运的是,在这种情况下,编译器非常明确地提到<>不适用于匿名类。

+1

很好的答案+1 – 2011-12-26 20:14:49

0

这不是真正的方法调用。独立声明

new Box<>(new Integer(10)); 

也编译。有足够的信息来推断TBox(即从整数参数)

在另一方面,这并不编译

new ArrayList<>(); 

有没有办法知道什么样的名单是需要的。

Collection<String> strings = new ArrayList<>(); 

这个工程,因为推理是由目标类型Collection<String>

+1

'新的ArrayList <>();'作为一个独立的语句*不*编译。 – Holger 2014-02-05 19:05:44

1

我不认为这是值得我们思考的,当它的工作原理,当没有帮助。编译器会告诉你,因此你必须重写什么不起作用。

没有它背后真正的理由;它更像开发商已经把实际的编译器实现的电流限制在特定的时间在说明书中告诉我们:这就是它必须是。

Java的8部电梯了很多这些限制没有地狱冻结了。例如。

Arrays.asList("foo", "bar").addAll(new ArrayList<>()); 

用Java 8编译没有任何错误。那么为何不?