我在JDK 1.8上将IntelliJ IDEA与javac一起使用。我有以下代码:
class Test<T extends Throwable>
{
@SafeVarargs
final void varargsMethod( Collection<T>... varargs )
{
arrayMethod( varargs );
}
void arrayMethod( Collection<T>[] args )
{
}
}
IntelliJ IDEA不会在上面的代码中突出显示任何内容作为警告。但是,在编译时,以下行将显示在“消息”视图的“生成”选项卡中:
警告:(L,C)java:Varargs方法可能会导致不可修改的varargs参数varargs造成堆污染
注意#1:我已经指定了@SafeVarargs
。
注意#2:Warning:(L,C)
指向varargs
作为参数传递给arrayMethod()
假设我知道自己在做什么,并且假设我非常确定不会出现堆污染,或者我保证不会以某种时髦的方式调用此方法,这可能会导致堆污染,
那么我需要做些什么?禁止显示此警告消息?
注意:
关于varargs方法,有很多关于问题,但是似乎没有一个问题可以解决此特定问题。实际上,整个interwebz在回答这个特定问题方面似乎很差。
在这个问题上,我所看到的答案都没有一个令人满意,因此,我认为自己会对此持怀疑态度。
这是我的看法:
@SafeVarargs
[unchecked] Possible heap pollution from parameterized vararg type Foo
。@SuppressWarnings("varargs")
是解决警告的方法:[varargs] Varargs method could cause heap pollution from non-reifiable varargs parameter bar
。
因此,如果我对OP的原始代码进行以下简单修改:
class Foo {
static <T> void bar(final T... barArgs) {
baz(barArgs);
}
static <T> void baz(final T[] bazArgs) { }
}
$ javac -Xlint:all Foo.java
使用Java 9.0.1编译器的输出为:
Foo.java:2: warning: [unchecked] Possible heap pollution from parameterized vararg type T
static <T> void bar(final T... barArgs) {
^
where T is a type-variable:
T extends Object declared in method <T>bar(T...)
1 warning
我可以通过将标记bar()
为来消除该警告@SafeVarargs
。这既使得警告消失 ,并
通过增加可变参数安全的方法合同,确保任何人谁通话bar
将不必抑制任何可变参数的警告。
但是,这也使Java编译器更加仔细地查看了方法代码本身-
我想是为了验证一些简单的情况,在这些情况下bar()
可能违反了我刚刚订立的合同@SafeVarargs
。而且它看到bar()
所调用baz()
传递barArgs
和数据,因为baz()
需要一个Object[]
因类型擦除,baz()
会搞乱了堆,从而导致bar()
以传递地做到这一点。
因此,我还需要添加@SuppressWarnings("varargs")
,bar()
以使有关bar()
的代码的警告消失。
问题内容: 我知道在Java 7中使用带有泛型类型的varargs时会发生这种情况。 但是我的问题是.. Eclipse说“使用它可能会污染堆”时,这到底是什么意思? 和 新注释如何防止这种情况? 问题答案: 堆污染是一个技术术语。它引用的引用类型不是其指向的对象的超类型。 这可能会导致“无法解释” 。 @SafeVarargs完全不能阻止这一点。但是,有些方法证明不会污染堆,编译器无法证明这一点
我知道Java 7在使用泛型类型的varargs时会出现这种情况; 但我的问题是.. 当Eclipse说“它的使用可能会潜在地污染堆”时,它到底是什么意思? 而且 新的注释如何防止这种情况发生?
我目前正在设置IntelliJ Inspection Profile,以便它可以在编辑器中指出潜在的问题。但我并没有找到一种方法来指出javac警告“最后一个参数的参数类型不精确的varargs方法的非varargs调用;”。 考虑下面的片段: 在Eclipse中,方法调用,带有下划线(带有一条锯齿状的黄线),但在IntelliJ中,这似乎不会被检查发现。不过,当我在IntelliJ中编译文件时,
但是,如果Terminal中没有提供,我不知道如何(或者是否能够)为其设置默认值。像这样简单的东西不起作用。这里的一个解决方案是根据的内容或大小在函数中设置变量。但我不知道有没有更好的办法做到这一点。 因此,我正在寻找一种方法来使用来自终端的参数调用一个函数,其中需要一个数字(在本例中为2),而其余的是可选的,并设置为默认值。
问题内容: 考虑方法声明: 该Object …参数只是对Objects 数组的引用。有没有办法在引用实际Object数组时使用此方法?如果我将Object数组传递给…参数-结果参数值将是一个二维数组-因为an Object[]本身就是an Object: 因此,数组的第一个组件(String.format方法中使用了哪个)将是一个数组,他将生成: 然后由于数组大小为1而发生错误。 该大胆的顺序是真
问题内容: 这是我收到警告的示例代码。 警告: 警告:最后一个参数的参数类型不精确的varargs方法的无变量调用;转换为java.lang.Class以进行varargs调用转换为java.lang.Class []以进行非varargs调用并抑制此警告。Method method = aClass.getMethod(“ getInstance”,null); 请帮我解决这个问题 问题答案: