我们都知道,在Java中,如果你在Abstract
类中声明一个static
方法,该方法将属于Abstract
类,而不是它的子类。(没有abstract static
)
我有一个简单的数据库系统,它有一个Abstract
模型类:
public abstract class Model<T> {
// WON'T WORK (unfortunately I can't use abstract static)
public static T find(int id) {
...
}
}
如您所见,我无法在该类上创建返回泛型的静态方法,因为该方法不是继承的,因此它属于抽象类。
解决方法是在抽象类上创建一个受保护的方法,然后在其每个子类上创建一个静态方法:
public abstract class Model<T> {
protected T find(int id) {
...
}
}
public class User extends Model {
public static User find(int id) {
User dummy = new User();
return (User) dummy.find(id);
}
}
我觉得有更好的方法可以做到这一点。
有什么想法吗?
我可以想到两种可能的选择,尽管一种有点黑客。第一个是使Model<T>
成为一个普通类,并添加一个静态方法来获取模型,如下所示:
//I do not know how you want to do the user class, I just made it take the models class
private static final Model<User> MODEL = new Model<User>(User.class);
public static Model<User> model() {
return MODEL;
}
你会像这样使用它:User.model().find(id)
另一种选择是向类添加一个公共静态变量,static
导入该变量以调用其上的方法,就好像它是类而不是Model
实例一样。例如:
public class User {
public static Model<User> User = new Model<User>(User.class);
}
使用 static import my.package.User.User;
导入它将允许您使用 User user = User.find(id);
其中第一个User
是类名,第二个User
是静态变量。
否则,您将不得不将静态方法放在每个类中,因为不幸的是您无法继承或覆盖它们。
可以将静态泛型方法与扩展父类的类型一起使用。 但是,您将需要该类型的实例才能返回类型 T。 最简单的方法是传入调用方,但它可能只是一个空实例。
例如,您可以执行以下操作:
//No more generic Model
public abstract class Model
{
//Our generic static method; we need caller to get something of type T to return.
public static <T extends Model> T find(int id, T caller)
{
...
return caller.getMyReturnObject(id);
}
}
要调用它,您只需执行
Model model = find(someId, new Model{...})
其中,如果new Model{...}
在作为 Model
的子类中调用它,则可以将其替换为 this
。
如果您需要在方法中创建 T 的新实例,那么您仍然需要传入一些东西作为 T(调用者仍然有效)并使用反射创建新实例(使用 (T) type.getClass().newInstance();
而不是 new T()
)。