-1

So basically, I'm trying to get a Minecraft variable (unsupported version, and nobody knew how when it was anyways) and I need to change the block the variable has, to a new block. I checked this issue out and it turns out trying to set a final variable doesn't work as the code using it still returns the old value, while code using the reflected variable returns the new value. There is someone who got this working for 1.7.2, but I am using 1.7.10 and the code no longer works on that version, I tested it a while ago. I unfortunately could not find the thread where this code originates from and I no longer have it.

I want "new BlockFence("planks_oak", Material.wood)" to be changed to "new BlockNewFence("planks_oak", Material.wood)" in this line, but I'm pretty new to reflections and would have no idea how. Here's the line:

blockRegistry.addObject(85, "fence", (new BlockFence("planks_oak", Material.wood)).setHardness(2.0F).setResistance(5.0F).setStepSound(soundTypeWood).setBlockName("fence"));

Thanks for reading, if you have. I've tried this myself but honestly got nowhere as I'm really unsure of what to do to achieve this, I really only know how to get and set a private/protected field but as I found earlier final fields don't really work the same way. Please let me know if I need to provide more information. The reason why I brought up final fields and stuff earlier is because both blockRegistry is final, as well as the variable that uses this registry entry.

  • 3
    If it's final, then you probably shouldn't change it – user May 12 '20 at 15:40
  • Changing it is the only way to do what I want to do. I know where I could put the reflection so it patches the line of code before the variable is set, I just need to know *how* to do that. – Roadhog360 Gaming May 12 '20 at 15:43
  • 1
    This is not a final variable, what you have shown here is a method call to some method called `addObject` – Johannes Kuhn May 12 '20 at 16:00
  • The variable I need to access that uses this registry calls this method. Simply removing the object and adding my own in will crash the game. – Roadhog360 Gaming May 12 '20 at 16:20
  • Does this answer your question? [Change private static final field using Java reflection](https://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection) – Johannes Kuhn May 12 '20 at 20:27

1 Answers1

1

It is simple, you can try. But please aware that it is not a good approach. You may suffer unpredicted behaviors.

static class Value {
    public static final Integer VALUE = 10;
}

static void setFinalField(Field field, Object newValue) throws Exception {
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, newValue);
}
public static void main(String args[]) throws Exception {
    setFinalField(Value.class.getField("VALUE"), 200);
    System.out.println(Value.VALUE); //200 here
}
Peter Wang
  • 104
  • 4