Java логическое возвращение true, когда объявлено как false

В настоящее время я делаю плагин из 1.8 Bukkit API. Этот вопрос, однако, имеет отношение к логическим значениям. С самого начала моего файла класса, у меня есть это объявление логического

public static boolean lockchat = false;

Затем у меня есть еще один логический в файле класса, который используется для команд Bukkit:

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

Это логическое значение возвращает true в конце, которое, я думаю, делает lockchat логическое возвращение также верно. Если я верну false, я почти уверен, что код команды не вернется пользователю.

Моя проблема в том, что в этой части моего кода:

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

Объявление в начале здесь, кажется, не имеет значения, потому что это всегда отправляет мне сообщение разблокированным.

Я попытался поместить объявление внутри второго логического значения, но оно выдает мне ошибки и предупреждения.

Поскольку второе логическое значение возвращает значение true, я думаю, что lockchat логическое тоже возвращается. Если бы я изменил его, чтобы вернуть ложь, lockchat вероятно, также вернет false, что приведет к другой проблеме.

Я хочу найти способ, чтобы логическое объявление оставалось ложным, в то время как оно изменялось на true/false внутри второго логического значения, как показано. Как бы я это сделал?

ПРИМЕЧАНИЕ. Эта переменная больше нигде не используется в моем коде.

РЕДАКТИРОВАТЬ: я не думаю, что это будет иметь значение, но я проверяю, чтобы строка метки была "lockchat"так же, как логическое имя. Это, вероятно, ничего не изменит, но просто даст больше информации.

КОД ФАЙЛА ПОЛНОГО КЛАССА:

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; Не модифицируется никакими другими файлами классов.

РЕДАКТИРОВАТЬ: я использую Java 7 для этого.

4 ответа

Решение

Просто чтобы вы знали, в своем полном исходном коде вы используете следующий код:

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

более конкретно, вы отправляете "разблокировано" независимо от того, по какому пути следует код.

Изменить: я переформатировал ваш код, чтобы уменьшить количество дублирования. Эта версия быстро дает сбой, если 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";
}

Как указано в ответе Джулиана, ваш код возвращается разблокированным независимо от значения:

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

Что касается вашего комментария относительно того, почему он не блокирует чат, вы уверены, что зарегистрировали своего слушателя? Чтобы зарегистрировать слушателя, поместите эту строку в метод onEnable() вашего основного класса:

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

Где DCCommandLockChat() - ваш класс Listener, а "this" - ваш класс, расширяющий JavaPlugin.

Что в основном делает, это регистрирует ваш слушатель для вашего плагина, потому что в противном случае сервер не передал бы никаких событий вашему слушателю, и поэтому ваш слушатель не знал бы, что будет происходить на сервере.

Кроме того, что касается самого метода, возвращающего true или false, оба значения все равно будут запускать команду. Насколько я знаю, единственное время, когда возвращаемое значение метода onCommand имеет значение, это когда вы используете псевдонимы в вашем plugin.yml. Если метод возвращает false, сервер отправит игроку сообщение с псевдонимами. Кроме того, это не имеет значения.

Вы должны дать логическое (lockchat) значение, которое вы хотите в конструкторе вашего класса.

Чтобы ответить на ваш вопрос:

Я хочу найти способ, чтобы логическое объявление оставалось ложным, в то время как оно изменялось на true/false внутри второго логического значения, как показано. Как бы я это сделал?

В начале тела любого оператора, который вы хотите, создайте временную переменную для хранения lockChatценность.

boolean lockChatTemp = lockChat;

Затем используйте и измените это значение в вашей функции. Сюда, lockChat сохранит свою ценность во всем.

Также,

if (lockChat == true)

можно заменить на

if (lockChat) поскольку утверждение в скобках оценивается как boolean, а также lockChat уже boolean,

Другие вопросы по тегам