当前位置: 首页 > 面试题库 >

Java 7中的简化Varargs方法调用

贺功
2023-03-14
问题内容

在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或使用强类型变量调用该方法。请参见下面的示例: 输出