这是我的代码:
final String run_tool ="cmd.exe /C pelda.exe";
final Process tool_proc = null;
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
InputStream toolstr = tool_proc.getInputStream();
在eclipse将此警告消息发送到tool_proc变量之后:
最终的局部变量tool_proc 不能分配,因为它是 在封闭类型中定义
我不知道为什么我的代码不起作用
请帮帮我
答案 0 :(得分:6)
final
修饰符禁止在设置变量后更改变量。凯文给出了一个很好的解释,说明为什么你不能在这种情况下使用它。
您选择的构造要求您在父类中引入一个字段并通过run()
进行设置:
class MyClass {
Process tool_proc = null;
void myFunction() {
final String run_tool ="cmd.exe /C pelda.exe";
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
// tool_proc will be null at this point!
InputStream toolstr = tool_proc.getInputStream();
}
}
在上面的代码中,我已经证明tool_proc
在最后一行总是null
,因为线程在所有可能性中都没有完成它的执行!
您可以期待NullPointerException
s!
您尝试做的似乎与this article about capturing application output asynchronously非常相似。这是一个很好的阅读,并解释了为什么传统方法可能会导致问题。我的实现非常类似于StreamGobbler
(第4页)。
答案 1 :(得分:2)
我知道一个很好的技巧,因为我是C ++编码器并且总是想要java中的指针:
final String run_tool ="cmd.exe /C pelda.exe";
final Process tool_proc[] = new Process[1];
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc[0] = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
InputStream toolstr = tool_proc.getInputStream();
答案 2 :(得分:1)
tool_proc
变量为final
- 最终变量只能分配一次,并且您已在声明中为其指定了值null
。删除null
赋值将不起作用,因为可以多次调用runnable,从而导致多次赋值。 所以你最好的选择是删除 final
关键字,它应该编译,至少
正如我对我的回答的评论中所指出的,我忽略了tool_proc
是一个局部变量的事实,并且没有final
修饰符,无法从匿名{{1}访问它子类。保罗在他的回答中首先指出,你必须使用非最终字段来存储Runnable
对象。
答案 3 :(得分:-2)
无法更改最终字段的初始值。从tool_proc中删除最终修改器:
Process tool_proc = null;