@SafeVarargs是否适合此方法?

时间:2015-05-08 18:11:21

标签: java variadic-functions type-safety

我有一些Java代码(使用Guava ImmutableList类):

@Nonnull
public static <E extends Event> UserHistory<E> forUser(long id, E... events) {
    List<E> list = ImmutableList.copyOf(events);
    return new BasicUserHistory<E>(id, list);
}

我正在获得通常的堆污染警告,这些警告来自这样的方法。由于我的方法没有对events进行任何修改,因此它不能引入堆污染。但是,如果(因为擦除)此方法的客户端使用错误的events数组调用它,它似乎可以通过自身传播堆解析。

如果我使用@SafeVarargs对其进行注释,我仍会收到警告(使用@SuppressWarnings("varargs")可以抑制)。但是阅读heap pollution上的Java文档,我对这个方法的正确注释集有点不清楚。

我还注意到ImmutableList.copyOf 标记为@SafeVarargs(虽然这只是兼容性问题),但Arrays.asList是。

所以,我的问题是:@SafeVarargs是这个方法的合适注释,因为它不会遇到ClassCastException,但可能会将一个不正确检查的数组传播到最终的参数化类型并允许客户端代码中的ClastCastException

我相信,基于this answer,它是安全的,因为代码不会做任何取决于events本身类型的事情,只会根据其元素的类型。这是指南的正确应用吗?

1 个答案:

答案 0 :(得分:11)

是的,@SafeVarargs应该是合适的,因为events所做的唯一事情就是将其传递给ImmutableList.copyOf(),(我对该方法的理解)不依赖于ImmutableList.copyOf()在该数组的运行时类型上。

@SafeVarargs 应使用@SuppressWarnings("varargs")进行注释,但是 它不是(可能是向后兼容或他们没有注意到它)。当你的不可恢复的varargs方法将varargs参数传递给另一个可能依赖于数组的运行时类型的方法时,那么(由于我不完全理解的原因,但是this question的主题),它给出了你是那个电话的警告。这可以通过make_shared来抑制。