Varargs 污染堆

Varargs polluting the heap

Java 没有文字地图语法,所以我正在尝试使用文字初始化地图的方法。编译器警告 Possible heap pollution from parameterized vararg type 这对我来说是新的,所以我读到了。我认为我可以安全地使用相关注释来抑制这些警告。但是我有两个相关的问题。

  1. 在这种情况下可以禁止显示警告,我说得对吗? (对于下面的代码)
  2. 为什么 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 可以安全地用作 :

  • KV 参数类型在编译时限制在您实例化时指定的泛型 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 注释不会发出警告。