采用数组的Java模板类;有什么方法可以强制执行吗?

时间:2010-08-03 20:46:31

标签: java

我正在编写一个模板类,它应该以数组作为类型。

public class Foo<T> {...}

我如何才能强制执行“T”是一种数组类型? (int [],Bar [],...)显然,如果可能的话,最好是编译时间,但是如果T不是数组,那么在调试运行时抛出异常的最佳方法是什么?

4 个答案:

答案 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)

@emory在没有运行时检查的情况下,可以通过干净的方式完成此操作。就个人而言,我会关注类型名称的可读性 - 这是一个使用内部类的非常紧凑的例子,我认为最终得到的类型名称非常易读。

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();