由于Java泛型的实现,您不能拥有这样的代码:
public class GenSet<E> {
private E a[];
public GenSet() {
a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
}
}
Run Code Online (Sandbox Code Playgroud)
如何在保持类型安全的同时实现这一点?
我在Java论坛上看到了这样的解决方案:
import java.lang.reflect.Array;
class Stack<T> {
public Stack(Class<T> clazz, int capacity) {
array = (T[])Array.newInstance(clazz, capacity);
}
private final T[] array;
}
Run Code Online (Sandbox Code Playgroud)
但我真的不知道发生了什么.
我最近遇到了java @SafeVarargs注释.谷歌搜索使Java中的可变函数不安全的原因让我感到困惑(堆中毒?擦除类型?),所以我想知道一些事情:
是什么让可变参数Java函数在@SafeVarargs意义上不安全(最好以深入的例子的形式解释)?
为什么这个注释留给程序员自行决定?这不是编译器应该能够检查的东西吗?
是否有必须坚持一些标准,以确保他的功能确实安全?如果没有,确保它的最佳做法是什么?
我们使用了一些varargs函数,当我们转向java 1.7时,我们得到了一个奇怪的未经检查的警告.
功能在接口ICache中添加
public interface ICache<O> {
void add(Object source, O... objects);
}
Run Code Online (Sandbox Code Playgroud)
在界面中报告错误.
ICache.java:18: warning: [unchecked] Possible heap pollution from parameterized vararg type O
void add(Object source, O... objects);
where O is a type-variable:
O extends Object declared in interface ICache
1 warning
Run Code Online (Sandbox Code Playgroud)
O扩展了Object,作为其通用缓存类.
我阅读了xlint警告并且我们在未经检查的情况下编译,但是http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#xlintwarnings似乎暗示这个错误应该是[varargs]类型不是未经检查的类型.
我错过了什么吗?
我有一些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);
}
Run Code Online (Sandbox Code Playgroud)
我得到了通常的堆污染警告,这种警告来自这样的方法.由于我的方法没有做任何修改events
,所以不能引入堆污染.但是,如果(因为擦除)此方法的客户端使用错误的events
数组调用它,它似乎可以通过自身传播堆解决方案.
如果我用它注释@SafeVarargs
,我仍然会收到警告(可以抑制@SuppressWarnings("varargs")
).但是阅读关于堆污染的Java文档,我对这个方法的正确注释集有点不清楚.
我也注意到,ImmutableList.copyOf
在没有标记为@SafeVarargs
(尽管这可能仅仅是一个兼容性问题),但是Arrays.asList
是.
所以,我的问题:@SafeVarargs
这个方法是一个合适的注释,因为它不会遇到一个ClassCastException
,但可能会将一个不正确检查的数组传播到最终的参数化类型并允许一个ClastCastException
客户端代码?
我相信,基于这个答案,它是安全的,因为代码不会做任何取决于events
它自身类型的东西,只取决于它的元素类型.这是指导的正确应用吗?
这个问题特定于使用带有泛型的varargs Enum<E>
:
Type safety: Potential heap pollution via varargs parameter elements
如果我像这样定义方法,为什么会收到此警告:
<E extends Enum<E>> void someMethod(E... elements)
Run Code Online (Sandbox Code Playgroud)
与此相反:
<E extends Enum<E>> void someMethod(E[] elements)
Run Code Online (Sandbox Code Playgroud)
因此,在声明方法之前我应该注意什么@SafeVarargs
?
这个问题类似于这些问题,Collection<T>...
但这些答案中显示的情景似乎不适用于Enum<E>...
:
与此问题相反,它质疑为什么没有警告:
这是我试图污染堆的原因,但每次不良尝试都会产生java.lang.ArrayStoreException
污染,而不是污染的数组.
我正在使用Eclipse 4.6.0和Java JDK 8u74.
public static void main(String[] args) {
Foo[] x = { Foo.A };
someMethod(x);
Foo y = x[0]; // How does one get a ClassCastException here?
}
private …
Run Code Online (Sandbox Code Playgroud) 我试图有一个handleException
方法,它可以采用异常对象和可接受的异常类列表来检查异常是否可以接受并且可以重试.
void handleException(Exception e, String... acceptableExceptionNames)
throws MyException {
boolean isRetryable = false;
for(String acceptableExceptionName: acceptableExceptionNames) {
try {
if (Class.forName(acceptableExceptionName).isInstance(e)) {
isRetryable = true;
break;
}
} catch (ClassNotFoundException e1) {
continue;
}
}
if (isRetryable) {
// log retryable
} else {
// log error
}
throw new MyException(isRetryable, "Failed");
}
Run Code Online (Sandbox Code Playgroud)
我传入的参数是a String... classNames
而不是Class<? extends Exception> classes
,因为如果我做这样的事情:
void handleException(
Exception e,
Class<? extends Exception>... acceptableExceptions)
throws MyException {
for (Class acceptableException : acceptableExceptions) …
Run Code Online (Sandbox Code Playgroud) 我对编程比较陌生,过去两天我一直想知道如何制作一个由其他Predicates自定义列表组成的谓词.所以我想出了一些解决方案.下面是一个代码片段,可以给你一个想法.因为我是基于单独阅读各种文档而编写的,所以我有两个问题:1 /它是一个很好的解决方案吗?2 /是否有其他一些推荐的解决方案可以解决这个问题?
public class Tester {
private static ArrayList<Predicate<String>> testerList;
//some Predicates of type String here...
public static void addPredicate(Predicate<String> newPredicate) {
if (testerList == null)
{testerList = new ArrayList<Predicate<String>>();}
testerList.add(newPredicate);
}
public static Predicate<String> customTesters () {
return s -> testerList.stream().allMatch(t -> t.test(s));
}
}
Run Code Online (Sandbox Code Playgroud) java ×7
java-7 ×2
arrays ×1
enums ×1
exception ×1
generics ×1
java-8 ×1
java-stream ×1
javac ×1
lambda ×1
predicate ×1
reflection ×1
type-safety ×1