我有一个基础Entity
类:
public class Entity
{
abstract int getTypeID();
}
方法int getTypeID()
返回该类唯一的数字:
public class OneEntity extends Entity
{
int getTypeID()
{
return 1; // Actually defined in a constants class
}
}
现在我希望能够安全地投射并分配它。
我可以这样做:
public void castTheEntityAndDoSomething(Entity ent)
{
if (isType(ent, 1)) // this is the 1 from the OneEntity class
{
OneEntity oneEnt = (OneEntity)ent;
// ... and then do something
}
}
public bool isType(Entity ent, int type)
{
return ent.getTypeID() == type;
}
但我想要做的是将演员表和类型检查合并在一行中。
类似的东西:
if (OneEntity oneEnt = entityCast(ent, 1))
{
// use a method specific to the OneEntity class
}
这可能吗?该方法是什么样的? 如果我可以使用子类名作为安全转换方法的参数,那会更好。
编辑:
所以我写了这个方法以避免类型id等。
@SuppressWarnings("unchecked")
public static <T extends Entity> T castEntity(Entity ent)
{
if (ent instanceof T)
{
return (T)ent;
}
return null;
}
但它有这个错误:
无法对类型参数T执行instanceof检查。请改为使用其擦除实体,因为泛型类型信息将在运行时被删除
我需要做些什么来解决这个编译错误?这是否正朝着正确的方向发展?
答案 0 :(得分:2)
如果您仅为了投射而定义了此typeId
,那么请不要这样做,而是使用instanceof
运算符。
然后你只需要做这样的事情,
if (ent instanceof EntityOne) {
OneEntity oneEntity = (OneEntity) ent;
// do whatever
}
现在,举个例子,
if (Entity oneEnt = entityCast(ent, 1))
{
// do something with oneEnt
}
假设您的if
语句有效,而entityCast()
方法返回OneEntity
。你不认为你再次获得Entity
类型的返回值。因此破坏了整个目的。
所以,请解释你想要做什么。
答案 1 :(得分:1)
如果你实现了一个接口来定义你想要从“do something”块调用它们的方法,并在所有派生的entiries中实现这个接口,你就可以通过使用多态来解决问题。
答案 2 :(得分:1)
您可能想重新考虑您的架构 首先,也许你不应该在课堂上有一个typeID字段 您应该依赖继承和/或接口的“强大”。
// Entity.java
public interface Entity { abstract public void doSomeThing(); }
// EntityType1.java
public class OneEntity extends Entity {
@Override
public void doSomeThing() {
// do something specific for entity type 1
}
}
// EntityType2.java
public class TwoEntity extends Entity {
@Override
public void doSomeThing() {
// do something specific for entity type 2
}
}
// Main.java
public static void main(String[] args) {
Entity e1 = new EntityType1();
Entity e2 = new EntityType2();
e1.doSomeThing();
e2.doSomeThing();
}
您应该在实现类中封装不同的行为。
如果您认为有充分的理由将行为与实体分离,则最好在外部处理类的层次结构中使用相同的逻辑(可能在顶部使用简单的工厂),并在工厂方法中使用“instanceof”。
答案 3 :(得分:1)
我想你可以这样做:
OneEntity oneEnt;
if (isType(ent, 1) && (oneEnt = (OneEntity) ent) != null) {
// ... and then do something
}
...或等效于instanceof
而非您的isType
方法......
或者您可以按如下方式定义名为oneEntityOrNull
的方法:
public OneEntity oneEntityOrNull(Entity ent) {
return ent instanceof OneEntity ? (OneEntity) ent : null;
}
然后
OneEntity oneEnt;
if ((oneEnt = oneEntityOrNull(ent)) != null) {
// ... and then do something
}
但IMO这两个都是一个糟糕的IDEA,因为代码比原始代码更难理解。