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
,