java Java泛型方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5442134/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java generic method
提问by terryhau
I have a whole bunch of classes that define these two constants, eg:
我有一大堆定义这两个常量的类,例如:
public class Face
{
public static final int LUMP_INDEX = 1;
public static final int SIZE = 20;
blah blah
}
public class Edge
{
public static final int LUMP_INDEX = 5;
public static final int SIZE = 32;
blah blah
}
etc.
At the moment, i have a function for each one to create an array of that class, using the 2 constants defined in the class.
目前,我有一个函数为每个函数创建一个该类的数组,使用类中定义的 2 个常量。
private Face[] createFaces(RandomAccessFile in)
{
int numFaces = doSomeCalculations(Face.LUMP_INDEX, Face.SIZE);
Face[] faces = new Face[numPlanes];
blahblah;
for(int i = 0; i < numFaces; i++)
faces[i] = new Face();
return faces;
}
A bit silly to have a create function for every class. The only thing that changes is the class type. So i wanted to create a genertic method that would work with any of the classes above. Something like:
为每个类都有一个创建函数有点傻。唯一改变的是类类型。所以我想创建一个可以与上述任何类一起使用的泛型方法。就像是:
private T[] create(RandomAccessFile in, Class T)
{
int num = doSomeCalculations(T.LUMP_INDEX, T.SIZE);
T[] faces = new T[numPlanes];
blahblah;
for(int i = 0; i < num; i++)
faces[i] = new T();
return faces;
}
However I'm not sure how to do it properly. Any help would be appreciated. Thanks.
但是我不知道如何正确地做到这一点。任何帮助,将不胜感激。谢谢。
回答by Michael Borgwardt
The only way that could be made to work is by using reflection to read the constants through the class object and Array.newInstance()
to create the array. Oh, and the method signature would have to look like this:
唯一可行的方法是使用反射通过类对象读取常量并Array.newInstance()
创建数组。哦,方法签名必须是这样的:
private <T> T[] createFaces(RandomAccessFile in, Class<T> clazz)
EditAn alternative solution would be to keep the constants in a map keyed by class rather than as static fields. Java just isn't dynamic enough, especially on the class level, to do it your way cleanly.
编辑另一种解决方案是将常量保存在按类键控的映射中,而不是作为静态字段。Java 不够动态,尤其是在类级别,无法以您的方式干净利落地完成。
回答by Tom Hawtin - tackline
There's no excuse for using reflection in a situation like this. Bung in an Abstract Factory or similar.
在这种情况下没有理由使用反射。塞在抽象工厂或类似的地方。
回答by Dave C
Potentially you could do this by having both (all?) of the items you want to create extend some superclass "Array-Able Object"
可能你可以通过让你想要创建的两个(所有?)项目扩展一些超类“Array-Able Object”来做到这一点
But provided your "blablabla" in createFaces is not the same, you gain nothing and back yourself into a corner with that extension.
但是,如果您在 createFaces 中的“blablabla”不一样,您将一无所获,并通过该扩展将自己退回到角落。
I'd look into whether or not you really need these different classes which all do the same thing, or whether there's some more general fix you could look into. If the only difference between the two is their static variables, for instance- then you should move those to a single location, say- a resource file.
我会研究你是否真的需要这些不同的类,它们都做同样的事情,或者是否有一些更一般的修复你可以研究。例如,如果两者之间的唯一区别是它们的静态变量,那么您应该将它们移动到一个位置,比如一个资源文件。
If all you have the same, though, are those "create array" sections of this code, then separating or somehow linking them seems unnecessary at best.
但是,如果您拥有相同的代码的那些“创建数组”部分,那么分离或以某种方式链接它们似乎充其量是不必要的。
回答by Pablo Grisafi
You can always use the simpler form:
您始终可以使用更简单的形式:
<T> T[] create(RandomAccessFile in, Class<T> clazz, int lumpIndex, int size)
{
int numPlanes = doSomeCalculations(lumpIndex, size);
T[] faces = new T[numPlanes];
blahblah;
return faces;
}
And use it like
并像使用它一样
Face[] faces = create(in, Faces.class, Face.LUMP_INDEX, Face.SIZE
It is neither as professional as using an abstract factory, nor as silly (and dangerous!) as having the same function over and over again. You can still make the mistake of calling it using
它既不像使用抽象工厂那么专业,也不像一遍又一遍地使用相同的功能那么愚蠢(和危险!)。你仍然可以错误地使用调用它
Face[] faces = create(in, Faces.class, Edge.LUMP_INDEX, Edge.SIZE)
But this is a mistake that it is easy to point.
但这是一个很容易指出的错误。