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,则服务器将向玩家发送带有别名的消息。除此之外,这并不重要。
我目前正在从 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,则服务器将向玩家发送带有别名的消息。除此之外,这并不重要。