我正在编写一个模板类,它应该以数组作为类型。
public class Foo<T> {...}
我如何才能强制执行“T”是一种数组类型? (int [],Bar [],...)显然,如果可能的话,最好是编译时间,但是如果T不是数组,那么在调试运行时抛出异常的最佳方法是什么?
答案 0 :(得分:2)
不可能完全按照您的要求进行操作,并且通用类型指定数组或原语。
语法允许使用以下内容:
public class Foo <az09$_ extends MyClassOrInterface & Serializable & Closeable> {...}
其中az09 $ _是任何有效的标识符,也可以使用相同格式的泛型类型进行参数化。
但是az09 $ _仅限于作为java标识符,因此您不能public class Foo<T[]> {...}
执行public class Foo[] {...}
。
通常情况下,你会在使用T时做你想做的事,即:
public class Foo<T> {
public T[] processIt(T... ts) {
// do something
return ts;
}
}
答案 1 :(得分:1)
如果您确实想要检查类型是否是一个数组,可以在运行时使用以下代码完成,尽管这有点像黑客并且效率不高:
public static boolean isArrayType (Object o) {
return o.getClass().isArray();
}
最终,这取决于你想要做什么。
答案 2 :(得分:1)
我将同意并延长David Blevin's回答。您可以将MyClass放在工厂类中,并使MyClass的构造函数成为私有。这样,只有工厂类中的代码才能直接实例化MyClass。你应该确保他们做正确的事。您可以使工厂clas参数化(如下所示)或使make方法本身参数化。
// T is the component type of the array
public class MyClassFactory < T >
{
// we can't directly enforce TARRAY=T[], but TARRAY=T[]
public final class MyClass < TARRAY >
{
private MyClass ( ... arguments ) throws ... exceptions { ... code }
// no non private constructors
.... more code
}
// this is the only way to construct a MyClass
// so we indirectly enforced TARRAY=T[]
public MyClass<T[]> make ( ... arguments ) throws ... exceptions
{
return new MyClass <T[]>( ... arguments ) ;
}
}
答案 3 :(得分:0)
public static class Bar {}
public static class Foo<T> {
public static class Array<TA> {
private Array() {}
}
public Array<T[]> make() {
return new Array();
}
}
Foo.Array<Bar[]> fooray = new Foo<Bar>().make();