在Java 7中,可以选择添加@SafeVarargs
注释来抑制在编译带有不可修改的varargs参数的方法时收到的警告。Project
Coin的提案规定,当该方法确保仅将与varargs参数相同类型的元素存储在varargs数组中时,应使用注释。
非安全方法的一个例子是什么?
例如,foo()
不安全,可能会将非T存储在数组中,从而在[2]处引起问题
<T extends List<?>> void foo(T... args)
{
List<String>[] array2 = (List<String>[])args;
array2[0] = a_list_of_string;
}
void test2()
{
List<Integer>[] args = ...; // [1]
foo(args);
Integer i = args[0].get(0); // [2]
}
通过使用@SafeVarargs标记该方法,您可以向编译器保证您不会做任何类似的事情。
但是如何在[1]处获得通用数组呢?Java不允许创建通用数组!
通用数组创建的唯一批准方式是调用vararg方法时
foo( list_int_1, list_int_2 )
则调用者无法访问该数组,调用者无论如何也无法执行[2],foo()
与该数组的混乱程度无关。
但是然后您考虑一下,这 是 创建通用数组的后门
@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
return Arrays.copyOf(array, length);
}
List<String>[] array1 = newArray(10);
和通用数组文字
@SafeVarargs
static <E> E[] array(E... array)
{
return array;
}
List<String>[] array2 = array( list1, list2 );
因此,我们毕竟 可以 创建通用数组…愚蠢的Java,试图阻止我们这样做。
问题内容: 我想像这样的代码来获取有关Java7功能的详细信息 可以做这样的事情 但坦白说对我来说还不太清楚。请解释一下? 问题答案: Null-safe方法调用是针对Java 7提出的,作为Project Coin的一部分,但并未最终发布。 在此处查看所有建议的功能以及所有最终选择的功能-https: //wikis.oracle.com/display/ProjectCoin/2009Prop
我目前正在设置IntelliJ Inspection Profile,以便它可以在编辑器中指出潜在的问题。但我并没有找到一种方法来指出javac警告“最后一个参数的参数类型不精确的varargs方法的非varargs调用;”。 考虑下面的片段: 在Eclipse中,方法调用,带有下划线(带有一条锯齿状的黄线),但在IntelliJ中,这似乎不会被检查发现。不过,当我在IntelliJ中编译文件时,
问题内容: 以下代码无法编译。 发出编译时错误。 对test的引用是模棱两可的,varargspkg.Main中的方法test(int …)和varargspkg.Main中的方法test(float …) 这似乎很明显,因为方法调用中的参数值可以提升为 如果任何一个或两个参数都带有或作为后缀,则会进行编译。 但是,如果我们用相应的包装器类型表示方法签名中的接收参数,如下所示 那么对该方法的调用不
问题内容: 这是一个无法编译的代码示例: 有人可以告诉我这些方法模棱两可的原因吗?先感谢您。 问题答案: 考虑方法签名 和 在装箱和拆箱之前,通话不会是模棱两可的。为了确保与Java的早期版本兼容,该调用将保持明确。因此,重载解决方案的第一阶段不允许装箱,拆箱或可变Arity调用,这些操作都是在同一时间引入的。可变Arity调用是通过为最后一个参数(而不是数组)传递参数序列来调用varargs方法
有人能告诉我这些方法模棱两可的原因吗?提前谢谢你。
问题内容: 如果我有一个vararg Java方法并调用,则我和 都将null。但是,如果我呼叫f,则其本身为null。为什么会这样呢? 我应该怎么称呼这样的? 问题答案: 问题是,当你使用原义null时,Java不知道它应该是哪种类型。它可以是空对象,也可以是空对象数组。对于单个参数,假定为后者。 你有两种选择。将null显式转换为Object或使用强类型变量调用该方法。请参见下面的示例: 输出