Varargs 污染堆
Varargs polluting the heap
Java 没有文字地图语法,所以我正在尝试使用文字初始化地图的方法。编译器警告 Possible heap pollution from parameterized vararg type
这对我来说是新的,所以我读到了。我认为我可以安全地使用相关注释来抑制这些警告。但是我有两个相关的问题。
- 在这种情况下可以禁止显示警告,我说得对吗? (对于下面的代码)
- 为什么
keys
方法需要两个注释?省略其中任何一个都会让我对 "heap pollution" 警告有所不同,但对我来说两者听起来都一样。
您不必批评代码。我只是在玩
这是代码。
import java.util.*;
public class MapMaker<K, V>{
private K [] m_keys;
@SafeVarargs
@SuppressWarnings("varargs")
public final MapMaker<K, V> keys( final K... keys ){
m_keys = keys;
return this;
}
@SafeVarargs
public final Map<K, V> values( final V... values ){
if ( values.length != m_keys.length )
throw new IllegalArgumentException( "Mismatch - keys: " + m_keys.length + ", values " + values.length );
final Map<K, V> result = new HashMap<>();
for ( int i = 0; i < m_keys.length; i++ )
result.put( m_keys[ i ], values[ i ] );
return result;
}
public static void main( String [] args ){
final Map<Integer, String> mapIntStr = new MapMaker<Integer, String>()
.keys ( 1, 2, 3 )
.values( "One", "Two", "Three" );
System.out.println( mapIntStr );
final Map<String, String> mapStrStr = new MapMaker<String, String>()
.keys ( "1" )
.values( "One", "Two" );
}
}
输出为
{1=One, 2=Two, 3=Three}
Exception in thread "main" java.lang.IllegalArgumentException: Mismatch - keys: 1, values 2
at MapMaker.values(MapMaker.java:16)
at MapMaker.main(MapMaker.java:35)
Am I right that it's ok to suppress the warnings in this case?
此处 Varargs
可以安全地用作 :
K
和 V
参数类型在编译时限制在您实例化时指定的泛型 MapMaker
:
final Map<Integer, String> mapIntStr = new MapMaker<Integer, String>()
您不会对 vargs 变量执行不安全的转换,也不会将它们分配给已声明的 Object[]
数组以使用可能导致 java.lang.ArrayStoreException
(这不是堆污染,但也是有问题的)。
您使用的是泛型数组,而不是泛型集合数组。堆污染在此配置中不太常见,因为您没有可能包含可能触发 ClassCastException
.
的不兼容元素的集合
所以是的 @SafeVarargs
有道理。
Why do I need two annotations for the keys method?
用这两种方法注释 keys()
方法:
@SafeVarargs
@SuppressWarnings("varargs")
不需要。
@SafeVarargs
确实足够了,因为 java.lang.SafeVarargs
javadoc 指出:
Applying this annotation to a method or constructor suppresses
unchecked warnings about a non-reifiable variable arity (vararg) type
and suppresses unchecked warnings about parameterized array creation
at call sites.
您可能应该检查一下您的 IDE 配置。
我使用 javac
进行了测试,仅使用 @SafeVarargs
注释不会发出警告。
Java 没有文字地图语法,所以我正在尝试使用文字初始化地图的方法。编译器警告 Possible heap pollution from parameterized vararg type
这对我来说是新的,所以我读到了。我认为我可以安全地使用相关注释来抑制这些警告。但是我有两个相关的问题。
- 在这种情况下可以禁止显示警告,我说得对吗? (对于下面的代码)
- 为什么
keys
方法需要两个注释?省略其中任何一个都会让我对 "heap pollution" 警告有所不同,但对我来说两者听起来都一样。
您不必批评代码。我只是在玩
这是代码。
import java.util.*;
public class MapMaker<K, V>{
private K [] m_keys;
@SafeVarargs
@SuppressWarnings("varargs")
public final MapMaker<K, V> keys( final K... keys ){
m_keys = keys;
return this;
}
@SafeVarargs
public final Map<K, V> values( final V... values ){
if ( values.length != m_keys.length )
throw new IllegalArgumentException( "Mismatch - keys: " + m_keys.length + ", values " + values.length );
final Map<K, V> result = new HashMap<>();
for ( int i = 0; i < m_keys.length; i++ )
result.put( m_keys[ i ], values[ i ] );
return result;
}
public static void main( String [] args ){
final Map<Integer, String> mapIntStr = new MapMaker<Integer, String>()
.keys ( 1, 2, 3 )
.values( "One", "Two", "Three" );
System.out.println( mapIntStr );
final Map<String, String> mapStrStr = new MapMaker<String, String>()
.keys ( "1" )
.values( "One", "Two" );
}
}
输出为
{1=One, 2=Two, 3=Three}
Exception in thread "main" java.lang.IllegalArgumentException: Mismatch - keys: 1, values 2
at MapMaker.values(MapMaker.java:16)
at MapMaker.main(MapMaker.java:35)
Am I right that it's ok to suppress the warnings in this case?
此处 Varargs
可以安全地用作 :
K
和V
参数类型在编译时限制在您实例化时指定的泛型MapMaker
:final Map<Integer, String> mapIntStr = new MapMaker<Integer, String>()
您不会对 vargs 变量执行不安全的转换,也不会将它们分配给已声明的
Object[]
数组以使用可能导致java.lang.ArrayStoreException
(这不是堆污染,但也是有问题的)。您使用的是泛型数组,而不是泛型集合数组。堆污染在此配置中不太常见,因为您没有可能包含可能触发
ClassCastException
. 的不兼容元素的集合
所以是的 @SafeVarargs
有道理。
Why do I need two annotations for the keys method?
用这两种方法注释 keys()
方法:
@SafeVarargs
@SuppressWarnings("varargs")
不需要。
@SafeVarargs
确实足够了,因为 java.lang.SafeVarargs
javadoc 指出:
Applying this annotation to a method or constructor suppresses unchecked warnings about a non-reifiable variable arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites.
您可能应该检查一下您的 IDE 配置。
我使用 javac
进行了测试,仅使用 @SafeVarargs
注释不会发出警告。