gpt4 book ai didi

java - 反射值输出不正确

转载 作者:行者123 更新时间:2023-12-02 10:56:36 26 4
gpt4 key购买 nike

我目前正在开发一个项目,我决定创建一个新的测试项目来了解我失败的地方。我以简单的方式重新创建了我正在使用的类。我的测试项目如下所示:

enter image description here

这些是 Java 类。

ChunkGenerator

package chunk;

public interface ChunkGenerator {
WorldChunkManager getManager();
}

ChunkGeneratorAbstact

package chunk;    

public class ChunkGeneratorAbstract implements ChunkGenerator {
private WorldChunkManager c;

public ChunkGeneratorAbstract(WorldChunkManager c){
this.c = c;
}

@Override
public WorldChunkManager getManager() {
return c;
}
}

WorldChunkManager

package chunk;

import java.util.UUID;

public class WorldChunkManager {
private UUID uuid;

public WorldChunkManager(UUID uuid){
this.uuid = uuid;
}

public UUID getUuid() {
return uuid;
}
}

World

package world;

public class World {
private WorldProvider provider;

public World(WorldProvider provider){
this.provider = provider;
}

public WorldProvider getProvider(){
return provider;
}
}

Main

import chunk.ChunkGenerator;
import chunk.ChunkGeneratorAbstract;
import chunk.WorldChunkManager;
import world.World;
import world.WorldProvider;

import java.lang.reflect.Field;
import java.util.UUID;

public class Main {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
WorldChunkManager manager = new WorldChunkManager(UUID.randomUUID());
System.out.println("DEFAULT MANAGER UUID:" + manager.getUuid());

ChunkGeneratorAbstract chunkGeneratorAbstract = new ChunkGeneratorAbstract(manager);
System.out.println("ChunkGeneratorAbstract: " + chunkGeneratorAbstract.getManager());

ChunkGenerator generator = new ChunkGenerator() {
@Override
public WorldChunkManager getManager() {
return manager;
}
};

WorldProvider provider = new WorldProvider(generator);
System.out.println("DEFAULT PROVIDER: " + provider);

World world = new World(provider);

Field field = chunkGeneratorAbstract.getClass().getDeclaredField("c");
field.setAccessible(true);
WorldChunkManager manager1 = new WorldChunkManager(UUID.randomUUID());
field.set(chunkGeneratorAbstract, manager1);
System.out.println("CUSTOM MANAGER UUID: " + manager1.getUuid());

System.out.println("FINAL:" + world.getProvider().getGenerator().getManager().getUuid());

}
}

这是输入:

DEFAULT MANAGER UUID:7c85e3ec-2288-4427-aae3-ce9e0b72c581
ChunkGeneratorAbstract: chunk.WorldChunkManager@2b193f2d
DEFAULT PROVIDER: world.WorldProvider@355da254
CUSTOM MANAGER UUID: 98a89e86-3b81-4fc3-8b5d-f22645b1685a
FINAL:7c85e3ec-2288-4427-aae3-ce9e0b72c581

正如您在使用反射并设置 WorldChunkManager 后所看到的那样对于自定义的,我尝试打印 WorldChunkManager 的 UUID ,但由于某种原因,我一直得到原始的而不是定制的

最佳答案

此代码中有 2 个 ChunkGenerator 实例:

// 1
ChunkGeneratorAbstract chunkGeneratorAbstract = new ChunkGeneratorAbstract(manager);
// 2
ChunkGenerator generator = new ChunkGenerator() {
@Override
public WorldChunkManager getManager() {
return manager; // hard-coded to return manager
}
};

您使用反射来更改 chunkGeneratorAbstractWorldChunkManager,但 WorldProvider 是通过引用另一个来创建的:

WorldProvider provider = new WorldProvider(generator);
// ^^^^^^^^^
World world = new World(provider);

当您执行 world.getProvider().getGenerator() 时,它会返回另一个 ChunkGenerator,它被硬编码为返回 manager >.

我想您需要以这种方式创建 WorldProvider 才能看到您期望的行为:

WorldProvider provider = new WorldProvider(chunkGeneratorAbstract);
<小时/>

另外:

  1. 这个问题实际上与反射的使用无关。如果您在 ChunkGeneratorAbstract 类中创建了一个 setter 并使用了它,您就会遇到同样的问题。

  2. 像这样使用反射来设置私有(private)字段并不是一个好的做法。我们将类(和其他成员)的字段设为私有(private),作为与使用该类的代码签订的契约(Contract)的一部分。契约是使用该类的代码必须以某种方式使用它(由其设计者指定),并且不能依赖于私有(private)成员。通过使用反射来访问私有(private)成员,您就违反了该契约。

关于java - 反射值输出不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51686237/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com