Java 布尔值在声明为 false 时返回 true

Java boolean returning true when declared false

我目前正在从 1.8 Bukkit API 制作一个插件。然而,这个问题与布尔值有关。从我的 class 文件开始,我有一个布尔值

的声明
public static boolean lockchat = false;

然后我在 class 文件中有另一个用于 Bukkit 命令的布尔值:

public boolean onCommand(CommandSender s, Command cmd, String label, String[] args)

这个布尔值 return 最后为真,我认为这使得 lockchat 布尔值 return 也为真。如果我 return 为假,我很确定命令代码不会 return 给用户。

我的问题是在我的这部分代码中:

if(lockchat == true)
{
    s.sendMessage("unlocked.")
    lockchat = false;
}
else
{
    s.sendMessage("locked.");
    lockchat = true;
}

开头的声明在这里似乎无关紧要,因为它总是向我发送已解锁的消息。

尝试将声明放在第二个布尔值中,但它会抛出错误和警告。

由于第二个布尔值 returning 为真,我认为 lockchat 布尔值也是 returning。如果我将其更改为 return false,lockchat 可能也会 return false,从而导致另一个问题。

我想找到一种方法让布尔声明保持为假,同时在第二个布尔值内将其更改为 true/false,如图所示。我该怎么做?

注意:此变量未在我的代码中的其他任何地方使用。

编辑:我认为这不会有什么不同,但我正在测试标签字符串是否为 "lockchat",与布尔名称相同。这可能不会改变任何东西,只是提供更多信息。

完整 CLASS 文件代码:

package dev.td6.duocraft.commands;

import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;

import dev.td6.duocraft.main.Duocraft;

public class DCCommandLockChat implements CommandExecutor, Listener
{

    Duocraft plugin;

    public DCCommandLockChat(Duocraft instance)
    {
        plugin = instance;
    }

    public String colorize(String msg)
    {
        String coloredMsg = "";
        for(int i = 0; i < msg.length(); i++)
        {
            if(msg.charAt(i) == '&')
                coloredMsg += '§';
            else
                coloredMsg += msg.charAt(i);
        }
        return coloredMsg;
    }

    public static boolean lockchat = false;

    @SuppressWarnings("deprecation")
    public boolean onCommand(CommandSender s, Command cmd, String label, String[] args)
    {

        if(s instanceof Player)
        {
            Player p = (Player) s;

            if(label.equalsIgnoreCase("lockchat"))
            {
                if(p.hasPermission("duocraft.lockchat"))
                {
                    if(args.length >= 1)
                    {
                        if(args.length >= 2)
                        {
                            s.sendMessage("Too many arguments. </lockchat [time]>");
                        }
                        else
                        {
                            if(lockchat == true)
                            {
                                int time = Integer.valueOf(args[0]);
                                s.sendMessage("locked");
                                lockchat = true;
                                plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
                                {
                                    @Override
                                    public void run()
                                    {
                                        Bukkit.broadcastMessage("unlocked.");
                                        lockchat = false;
                                        plugin.getServer().getScheduler().cancelTasks(plugin);
                                    }
                                }
                                    , time*20, time*20);
                            }
                            else
                            {
                                int time = Integer.valueOf(args[0]);
                                s.sendMessage("locked.");
                                lockchat = true;
                                plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
                                {
                                    @Override
                                    public void run()
                                    {
                                        Bukkit.broadcastMessage("unlocked.");
                                        lockchat = false;
                                        plugin.getServer().getScheduler().cancelTasks(plugin);
                                    }
                                }
                                    , time*20, time*20);
                            }
                        }
                    }
                    else
                    {
                        if(lockchat == true)
                        {
                            s.sendMessage("unlocked");
                            lockchat = false;
                        }
                        else
                        {
                            s.sendMessage("unlocked");
                            lockchat = true;
                        }
                    }
                }
                else
                {
                    p.sendMessage("no access");
                }
            }

        }
        else
        {
            if(label.equalsIgnoreCase("lockchat"))
            {
                if(args.length >= 1)
                {
                    if(args.length >= 2)
                    {
                        s.sendMessage("Too many args. </lockchat [time]>");
                    }
                    else
                    {
                        if(lockchat == true)
                        {
                            int time = Integer.valueOf(args[0]);
                            s.sendMessage("locked.");
                            lockchat = true;
                            plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
                            {
                                @Override
                                public void run()
                                {
                                    Bukkit.broadcastMessage("unlocked.");
                                    lockchat = false;
                                    plugin.getServer().getScheduler().cancelTasks(plugin);
                                }
                            }
                                , time*20, time*20);
                        }
                        else
                        {
                            int time = Integer.valueOf(args[0]);
                            s.sendMessage("locked");
                            lockchat = true;
                            plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable()
                            {
                                @Override
                                public void run()
                                {
                                    Bukkit.broadcastMessage("unlocked");
                                    lockchat = false;
                                    plugin.getServer().getScheduler().cancelTasks(plugin);
                                }
                            }
                                , time*20, time*20);
                        }
                    }
                }
                else
                {
                    if(lockchat == true)
                    {
                        s.sendMessage("unlocked");
                        lockchat = false;
                    }
                    else
                    {
                        s.sendMessage("unlocked");
                        lockchat = true;
                    }
                }
            }
        }

        return true;
    }

    @EventHandler
    public void chatLocked(AsyncPlayerChatEvent e)
    {
        if(lockchat==false)return;
        Player p = e.getPlayer();
        if(p.hasPermission("duocraft.lockchat.bypass"))return;

        p.sendMessage("chat is locked.");
        e.setCancelled(true);

    }

}

编辑:另外 public static boolean lockchat = false; 未被任何其他 class 文件以任何方式修改。

编辑:我为此使用 Java 7。

您应该在 class.

的构造函数中为布尔值 (lockchat) 提供您想要的值

回答你的问题:

I want to find a way to have the boolean declaration stay false, while having it changed to true/false inside of the second boolean, as shown. How would I do this?

在你想要的任何语句的主体的开头,创建一个临时变量来存储 lockChat 的值。

boolean lockChatTemp = lockChat;

然后,在您的函数中使用和修改该值。这样,lockChat 将始终保持其值。

此外,

if (lockChat == true)

可以替换为

if (lockChat) 因为括号内的语句求值为 boolean,而 lockChat 已经是 boolean.

请注意,在您的完整源代码中,您使用了以下代码:

if(lockchat == true)
{
    s.sendMessage("unlocked");
    lockchat = false;
}
else
{
    s.sendMessage("unlocked");
    lockchat = true;
}

更具体地说,无论代码遵循哪条路径,您都在发送 "unlocked"。

编辑:我重新格式化了您的代码以减少一些重复。如果 CommandSender 是未经许可的玩家或标签不是 "lockchat",则此版本会很快失败。我推断其意图是在不带参数的情况下执行“/lockchat”应该立即切换锁定,而在带参数的情况下执行它应该使其切换指定的秒数然后切换回来。下面的代码应该这样做(至少确保 lockchat 始终具有预期值,但我还没有测试它。

此外,我不知道 Runnable 是否会在不同线程上调用,但如果是,您应该同步对共享 lockchat 变量的所有访问。至少,使它成为 volatile(正如我在下面所做的那样)可以防止线程之间对其实际值产生一些混淆。

public static volatile boolean  lockchat    = false;

public boolean onCommand(CommandSender s, Command cmd, String label, String[] args) {
    // If this is not the 'lockchat' command, then fail fast
    if (!label.equalsIgnoreCase("lockchat")) return true;

    // If s is a Player then check the player has permission and fail fast
    // if not.
    if (s instanceof Player) {
        Player p = (Player) s;
        if (!p.hasPermission("duocraft.lockchat")) {
            p.sendMessage("no access");
            return true;
        }
    }

    switch (args.length) {
    case 0:
        lockchat = !lockchat;
        s.sendMessage(lockchatStatus());
        break;
    case 1:
        int ticks = Integer.valueOf(args[0]) * 20;
        final boolean originalLockChat = lockchat;
        lockchat = !originalLockChat;
        s.sendMessage(lockchatStatus());
        plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
            @Override
            public void run() {
                lockchat = originalLockChat;
                Bukkit.broadcastMessage(lockchatStatus() + ".");
                plugin.getServer().getScheduler().cancelTasks(plugin);
            }
        }, ticks, ticks);
        break;
    default:
        s.sendMessage("Too many arguments. </lockchat [time]>");
        break;
    }
    return true;
}

private String lockchatStatus() {
    return lockchat ? "locked" : "unlocked";
}

如 Julian 的回答所述,无论值是什么,您的代码 return 都已解锁:

 if(lockchat == true)
                    {
                        s.sendMessage("unlocked");
                        lockchat = false;
                    }
                    else
                    {
                        s.sendMessage("unlocked");
                        lockchat = true;
                    }

根据你关于为什么它没有阻止聊天的评论,你确定你注册了你的听众吗?要注册您的侦听器,请将此行放在 Main class 的 onEnable() 方法中:

getServer().getPluginManager().registerEvents(new DCCommandLockChat(), this);

其中 DCCommandLockChat() 是您的侦听器 class,'this' 是您扩展 JavaPlugin 的 class。

这基本上是为您的插件注册您的侦听器,否则,服务器不会将任何事件传递给您的侦听器,因此您的侦听器将不知道服务器上会发生什么。

此外,至于方法本身 return 为 true 或 false,这两个值仍然 运行 命令。据我所知,只有当您在 plugin.yml 中使用别名时,onCommand 方法的 return 值才重要。如果方法 returns 为 false,则服务器将向玩家发送带有别名的消息。除此之外,这并不重要。