将 Two 类 添加到 ArrayList<Class> 会用两个重复项填充 arraylist

Adding Two Classes to ArrayList<Class> fills the arraylist with two duplicates

我在制作 Spigot 插件时制作了一个名为 ArrayList<Arena> 的 ArrayList。

public static ArrayList<Arena> all = new ArrayList<Arena>();

现在我有了 class,这是实例化步骤:

public Arena(String name, int min, int max) {
    Arena.name = name;
    Arena.layout = "default";
    Arena.customName = CManager.getPlugin().getArenaConfig().getString("arenas." + name + ".custom-name");

    ArenaManager.addToArenaList(this);
    ArenaManager.arenaNames.add(Arena.name);
    Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName()
            + "]" + ChatColor.GREEN + " [#] (Instanciated arena " + Arena.name + ")");

    Arena.min = min;
    Arena.max = max;
    Arena.world = Bukkit.getWorld(Arena.name);

    waiting = true;
    starting = false;
    game = false;
    finished = false;
}

我对这段看似简单的代码有疑问。

public static void addToArenaList(Arena a) {
    all.add(a);
    checkArena(a);
}

public static void checkArena(final Arena a) {
    Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
        public void run() {
            if (!(all.contains(a))) {
                Bukkit.getServer().getConsoleSender().sendMessage(
                        ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]" + ChatColor.RED
                                + " [E] (Error while adding arena " + a.getArenaName() + "to list)");
            } else {
                Boolean found = false;
                for (Arena f : all) {
                    if (f.getArenaName().equals(a.getArenaName())) {
                        if (found == true) {
                            Bukkit.getServer().getConsoleSender()
                                    .sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
                                            + ChatColor.RED + " [E] (Duplicate found with arena "
                                            + a.getArenaName());
                            continue;
                        }
                        found = true;
                    }
                }
                if (found == false) {
                    Bukkit.getServer().getConsoleSender()
                            .sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
                                    + ChatColor.RED + " [E] (Error while adding arena " + a.getArenaName()
                                    + "to list)");
                }
            }
        }
    }, 10L);
}

但出于某种原因,我得到了最后一个竞技场的副本,这也是该过程的第一阶段

public void onEnable() {
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Commands...."), ChatColor.YELLOW);
    registerCommands();
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Events...."), ChatColor.YELLOW);
    registerEvents();
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Registering Config...."), ChatColor.YELLOW);
    createFiles();
    Methods.sendColoredMessage(this, ChatColor.LIGHT_PURPLE, ("Attempting to load arenas...."), ChatColor.GOLD);
    ArenaManager.all.clear();
    ArenaManager.arenaNames.clear();
    ArenaManager.createArenas();
    Methods.sendColoredMessage(this, ChatColor.AQUA,
            (pdfFile.getName() + " has been enabled! (V." + pdfFile.getVersion() + ")"), ChatColor.GREEN);
}
public static void createArenas() {
    if (plugin.getArenaConfig().getConfigurationSection("arenas") != null) {
        int count = 0;
        ArrayList<String> listed = new ArrayList<String>();
        for (String arena : plugin.getArenaConfig().getStringList("enabled")) {
            count++;
            Bukkit.getServer().getConsoleSender()
                    .sendMessage(ChatColor.LIGHT_PURPLE + "[" + plugin.getPdfFile().getName() + "]"
                            + ChatColor.GREEN + " [" + count + "] (Loading arena " + arena + ")");
            int min = plugin.getArenaConfig().getInt("arenas." + arena + ".min");
            int max = plugin.getArenaConfig().getInt("arenas." + arena + ".max");

            new Arena(arena, min, max);
        }
        Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
                + plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] Loaded arenas are listed below:");
        for (Arena a : all) {
            if (listed.contains(a.getArenaName())) {
                continue;
            }
            Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
                    + plugin.getPdfFile().getName() + "]" + ChatColor.GREEN + " [A] - " + a.getArenaName());
            listed.add(a.getArenaName());
        }
    } else {
        Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.LIGHT_PURPLE + "["
                + plugin.getPdfFile().getName() + "]" + ChatColor.RED + " [E] No arenas have been found!");
    }
}

因此,如果我有 4 个竞技场,最后一个叫做 EndArena,在我的数组中,我最终会得到 4 个元素都具有相同的竞技场 class EndArena。我什么都试过了,我通常不喜欢寻求帮助(我更喜欢自己学东西)但这让我很烦恼,所以我不得不提交它。

还有我的竞技场YAML文件

YAML Config

出现这种情况是因为您没有正确使用对象。

据我了解您的代码,您想要创建某种 Arena,为该 Arena 分配一些值,然后将其添加到某个 ArenaManager。这可以。为此,您需要使用实例变量,这样每个创建的 Arena 都会有自己的名称。该特定实例的唯一性。

您在这里使用的是静态字段 - 静态在程序中的所有对象中都是相同的,这不是您在这里需要的(如果您需要竞技场计数器之类的东西,这将是有益的)。

请看一些例子:

想象一下,有一个非常简单和天真的人 class(按照你的方法)。

public class Person {
    private static String name;
    public Person(String name) {
         Person.name = name;
    }
}

如果你想做这样的事情: 新人("Adam"); 新人("Viktor");

您将以 2 个 person 实例结束(指向)一个静态变量,该变量最终将具有值 Victor。这肯定不是我们在这里需要的东西。为了使其正常工作,您需要使用实例变量:

public class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
}

现在,在我们的示例代码之后,您将有 2 个人,每个人都有不同的名字。如何访问它们并不重要,真正重要的是它们应该是实例字段——这意味着每个实例在内存中都有单独的块来保存这个值。如果该字段是静态的,它只是意味着所有不同的对象都有一个可能的变量值 - 每次您更改它都会为所有其他对象更改。

总结一下:

您应该使用实例字段而不是静态字段。

在你的构造函数中你有: Arena.name = 姓名; Arena.layout = "default";

这两行代码总是会覆盖你 Arena 中的静态字段 class。

在你的 Arena class 你有类似的东西(注意静态关键字):

private static String name;

您需要:

private String name; 

所以每个实例都有自己的名字。请阅读有关实例和静态字段的信息,这将使它更容易理解!这是 Java 教程中的示例文档:https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html 本教程将很好地涵盖这一切!