我有这段代码:
public void onPlayerInteract(PlayerInteractEvent event) {
final Action action = event.getAction();
Location l1 = null;
Location l2 = null;
if (action == Action.LEFT_CLICK_BLOCK){
l1 = event.getClickedBlock().getLocation();
} else if (action == Action.RIGHT_CLICK_BLOCK) {
l2 = event.getClickedBlock().getLocation();
}
Thread t = new Thread() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000*60*60);
Location maxx = l1.getX();
Location maxy = l1.getY();
Location maxz = l1.getZ();
Location minx = l2.getX();
Location miny = l2.getY();
Location minz = l2.getZ();
if(l1.getX() > l2.getX()){
//I can't execute this, errors!
}
} catch (InterruptedException ie) {
}
}
}
};
t.start();
它给了我错误,并说要将l1和l2改为决赛。如果我将l1和l2更改为总决赛,它会给我另一个错误,即l1 =等等,它表示要删除最后一个。
答案 0 :(得分:7)
l1
和l2
是方法onPlayerInteract()
的局部变量。在此方法中,您将创建一个使用这些局部变量l1
和l2
的匿名内部类。只有l1
和l2
为最终版时才可以执行此操作。但是根据定义,最终变量只能分配一次,然后分配null,然后为它们分配另一个值。因此,您需要将l1
和l2
复制到最终变量,并在匿名类中使用这些最终副本:
public void onPlayerInteract(PlayerInteractEvent event) {
final Action action = event.getAction();
Location l1 = null;
Location l2 = null;
if (action == Action.LEFT_CLICK_BLOCK){
l1 = event.getClickedBlock().getLocation();
} else if (action == Action.RIGHT_CLICK_BLOCK) {
l2 = event.getClickedBlock().getLocation();
}
final Location l1Final = l1;
final Location l2Final = l2;
Thread t = new Thread() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000*60*60);
Location maxx = l1Final.getX();
Location maxy = l1Final.getY();
Location maxz = l1Final.getZ();
Location minx = l2Final.getX();
Location miny = l2Final.getY();
Location minz = l2Final.getZ();
if(l1Final.getX() > l2Final.getX()){
// ...
}
} catch (InterruptedException ie) {
}
}
}
};
...
}
答案 1 :(得分:1)
public void onPlayerInteract(PlayerInteractEvent event) {
final Action action = event.getAction();
final Location blockLocation = event.getClickedBlock().getLocation();
final Location l1 = (action == Action.LEFT_CLICK_BLOCK) ? blockLocation : null;
final Location l2 = (action == Action.RIGHT_CLICK_BLOCK) ? blockLocation : null;
Thread t = new Thread() {
...
}
}
答案 2 :(得分:1)
您需要对匿名内部类使用final。 如您所知,最终参考不能修改。
JB Nizet的答案是正确的。
但请注意,而不是JB Nizet代码:
Location l1 = null;
Location l2 = null;
if (action == Action.LEFT_CLICK_BLOCK){
l1 = event.getClickedBlock().getLocation();
} else if (action == Action.RIGHT_CLICK_BLOCK) {
l2 = event.getClickedBlock().getLocation();
}
final Location l1Final = l1;
final Location l2Final = l2;
您可以使用以下代码
final Location l1;
final Location l2;
if (action == Action.LEFT_CLICK_BLOCK){
l1 = event.getClickedBlock().getLocation();
l2 = null;
} else if (action == Action.RIGHT_CLICK_BLOCK) {
l1 = null;
l2 = event.getClickedBlock().getLocation();
} else {
l1 = null;
l2 = null;
}
由于局部变量从未初始化(甚至为null),编译器通常会告诉您在使用它之前对其进行初始化。但是如果你在if / elseif / else结构的所有情况下初始化它,编译器肯定知道你已经在任何情况下初始化它。
无论如何,你的代码似乎没有任何意义,因为在任何情况下,l1或l2都将为null。因此,您的线程将始终抛出NullPointerException。
这里有一个解释为什么你必须使用final来进行匿名内部类: Why do we use final keyword with anonymous inner classes?
另请注意,如果(l1.getX()> l2.getX()){您不能使用该语句 因为getX()和getY()返回Location而无法使用>进行比较运营商。您应该考虑在Location类上使用Comparable,然后执行if(l1.getX()。compareTo(l2.getX())> 0){...}
答案 3 :(得分:0)
运行中的代码实际上是它自己的方法。您可以将其设为单独的可运行方法并传递y1& y2在实例化时,或者,声明y1& y2在跑步中。
答案 4 :(得分:0)
解决方案如@JB Nizet所解释,但您不需要复制变量,如果他们有setter方法。然后,您的代码将如下所示(同样修复空指针,如@:
所述)public void onPlayerInteract(PlayerInteractEvent event) {
final Action action = event.getAction();
final Location l1 = new Location(); // Assumming Location has a default constructor.
final Location l2 = new Location();
if (action == Action.LEFT_CLICK_BLOCK){
l1.setX(event.getClickedBlock().getLocation().getX());
l1.setY(event.getClickedBlock().getLocation().getY());
} else if (action == Action.RIGHT_CLICK_BLOCK) {
l2.setX(event.getClickedBlock().getLocation().getX());
l2.setY(event.getClickedBlock().getLocation().getY());
}
Thread t = new Thread() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(1000*60*60);
Location maxx = l1Final.getX();
Location maxy = l1Final.getY();
Location maxz = l1Final.getZ();
Location minx = l2Final.getX();
Location miny = l2Final.getY();
Location minz = l2Final.getZ();
if(l1.getX() > l2.getX()){
// ...
}
} catch (InterruptedException ie) {
}
}
}
};
...
}
@Kkkev asnwer也应该正常工作,但要注意空指针。