【问题标题】:Setting the Value of a Field With a Subclass of the Field's type使用字段类型的子类设置字段的值
【发布时间】:2015-05-22 01:43:02
【问题描述】:

我已经解决这个问题超过 12 个小时没有成功,所以如果有人可以帮助解决这个问题或提供不同的解决方案,我将永远感激不尽。我遇到的主要问题是使用类继承结构更改字段,我将尝试解释:

“craftPlayer”变量是 CraftPlayer 的一个实例,它是 CraftEntity 的子类。 CraftEntity 类包含一个具有变量“uniqueID”的实体对象。所以基本上我要做的就是改变“craftPlayer”的uniqueID变量。我无权访问任何课程,所以我正在使用反射。我目前遇到的问题是尝试更改“craftPlayer”内部的实体变量,但我无法找到获取该类实例的方法,因为“实体”变量实际上是 EntityPlayer 的一个实例而不是实体

我意识到这解释得非常糟糕,所以尽可能多地提出澄清问题。任何帮助将不胜感激。

        CraftEntity craftPlayer = (CraftEntity) player;
        @SuppressWarnings("unchecked")
        Class<CraftEntity> craftEntityClass = getCraftEntityClass((Class<CraftEntity>) craftPlayer.getClass());

        for (Field field : craftEntityClass.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getName().equals("entity")) {
                Object object = field.get(craftPlayer);
                EntityPlayer entity = (EntityPlayer) object;
                entity.uniqueID = new UUID(0L, 0L);
                field.set(entity, entity); //"entity" is really an instance of EntityPlayer which is a subclass of Entity so i am unable to change the field because upclassing does not seem to work
                break;
            }
        }

编辑:

这里是 CraftEntity 类,可以更好地展示我在做什么

public abstract class CraftEntity implements org.bukkit.entity.Entity {   
    protected final CraftServer server;
    protected net.minecraft.server.v1_5_R3.Entity entity;
    private EntityDamageEvent lastDamageEvent;
}

【问题讨论】:

  • 请张贴CraftEntity类声明
  • “无法更改” 什么意思?是否抛出异常?如果有,它说明了什么?
  • @Radiodef 我会得到一个 IllegalArgumentException 说:无法将 Entity 字段设置为 EntityPlayer,因为“entity”只是 Entity 的子类,它实际上是一个 EntityPlayer
  • 你想用field.set(entity, entity);做什么?你的意思是field.set(craftPlayer, entity);?请注意,如果您所做的只是更改entity 的字段,则无需调用set,因为您引用了craftPlayer 中的实体。
  • 另外,我觉得有必要说,如果您是编写CraftEntity 类的人,那么使用反射是一种完全错误的处理方式。只需将 entity 公开或创建一个 setter/getter。

标签: java inheritance reflection casting bukkit


【解决方案1】:

entity.uniqueID = new UUID(0L, 0L); 足以改变变量。 尝试将字段设置为新变量是多余的。

问题实际上是时间问题,这段代码是在播放器保存的数据加载之前被调用的,所以一旦我所做的更改被覆盖。

【讨论】:

    【解决方案2】:

    你想在这里做什么?

    field.set(entity, entity);
    

    如果您想更改“craftPlayer”对象中的字段,您不应该这样做吗?

    field.set(craftPlayer, entity);
    

    【讨论】:

    • 这不起作用,因为craftPlayer 不是 CraftEntity 对象。它是一个 CraftPlayer 对象,它是 CraftEntity 的子类,但无论 field.set() 需要确切的类型,因此它不起作用。我发现了问题。使用 field.set() 完全是多余的,只需设置 entity.uniqueID 变量就足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2014-04-14
    • 2012-12-19
    相关资源
    最近更新 更多