Java NullPointerException写入一个长字段-(对某些人来说这似乎有点数学负担)?
写long返回的NPE意味着计算阶乘 输入参数后,按下按钮,TextView将返回结果 真的很简单…(我在做梦) long是名为ComputationRange的静态类中的私有字段 ComputationRange在exercies4(一个片段)类中,该类具有计算阶乘的所有业务逻辑,并连接到UI 日志清楚地表明,第237行返回了NULLPOINTEREXCEPTION,之后会出现进一步的错误 如需进一步信息,请直接询问 我会把这个班包括在这里Java NullPointerException写入一个长字段-(对某些人来说这似乎有点数学负担)?,java,android,nullpointerexception,Java,Android,Nullpointerexception,写long返回的NPE意味着计算阶乘 输入参数后,按下按钮,TextView将返回结果 真的很简单…(我在做梦) long是名为ComputationRange的静态类中的私有字段 ComputationRange在exercies4(一个片段)类中,该类具有计算阶乘的所有业务逻辑,并连接到UI 日志清楚地表明,第237行返回了NULLPOINTEREXCEPTION,之后会出现进一步的错误 如需进一步信息,请直接询问 我会把这个班包括在这里 在initThreadComputationRa
在
initThreadComputationRanges()
中,您没有在mThreadsComputationRanges[0]
中实例化对象,而是尝试写入其开始
字段。for循环only inits index>0。哪一行是第237行?并且请添加堆栈跟踪只能是这一行mComputationTimeoutTime=System.currentTimeMillis()+timeOut代码>但超时类型为int
,并且currentTimeMillis()
返回long
。看不到NPE:-(
public class Exercise4Fragment extends BaseFragment {
public static Fragment newInstance() {
return new Exercise4Fragment();
}
private static int MAX_TIMEOUT_MS = 1000;
private final Handler mUiHandler = new Handler(Looper.getMainLooper());
private EditText mEdtArgument;
private EditText mEdTimeOut;
private Button mBtnStart;
private TextView mtxtResult;
private int mNumberOfThreads;
private ComputationRange[] mThreadsComputationRanges;
private volatile BigInteger[] mThreadsCOmputationResults;
private final AtomicInteger mNumOfFinishedThreads = new AtomicInteger(0);
private long mComputationTimeoutTime;
private volatile boolean mAbortComputation;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_exercise_4, container, false);
mEdtArgument = view.findViewById(R.id.edt_argument);
mEdTimeOut = view.findViewById(R.id.edt_timeout);
mBtnStart = view.findViewById(R.id.btn_compute);
mtxtResult = view.findViewById(R.id.txt_result);
mBtnStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mEdtArgument.getText().toString().isEmpty()) {
return;
}
mtxtResult.setText("");
mBtnStart.setEnabled(false);
InputMethodManager imm =
(InputMethodManager) requireContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mBtnStart.getWindowToken(), 0);
int argument = Integer.valueOf(mEdtArgument.getText().toString());
computeFactorial(argument, getTimeOut());
}
});
return view;
}
private void computeFactorial(final int argument,final int timeOut) {
new Thread(() -> {
initComputationParams(argument, timeOut);
startComputation();
waitForThreadsResultsOrTimeoutOrAbort();
processComputationResults();
}).start();
}
@WorkerThread
private void processComputationResults() {
String resultString;
if(mAbortComputation){
resultString = "Computation aborted";
}
else {
resultString = computeFinalResult().toString();
}
if(isTimeOut()) {
resultString = "Computation timed out";
}
final String finalResutString = resultString;
mUiHandler.post(() -> {
if(!Exercise4Fragment.this.isStateSaved()) {
mtxtResult.setText(finalResutString);
mBtnStart.setEnabled(true);
}
});
}
private BigInteger computeFinalResult() {
BigInteger result = new BigInteger("1");
for(int i = 0; i < mNumberOfThreads; i++) {
if(isTimeOut()) {
break;
}
result = result.multiply(mThreadsCOmputationResults[i]);
}
return result;
}
@WorkerThread
private void waitForThreadsResultsOrTimeoutOrAbort() {
while(true) {
if(mNumOfFinishedThreads.get() == mNumberOfThreads) {
break;
} else if(mAbortComputation) {
break;
} else if(isTimeOut()) {
break;
} else {
try {
Thread.sleep(100);
}catch (InterruptedException e) {
}
}
}
}
@WorkerThread
private void startComputation() {
for(int i = 0; i < mNumberOfThreads; i++) {
final int threadIndex = i;
new Thread(() -> {
long rangeStart = mThreadsComputationRanges[threadIndex].start;
long rangeEnd = mThreadsComputationRanges[threadIndex].end;
BigInteger product = new BigInteger("1");
for(long num = rangeStart; num <= rangeEnd; num++) {
if(isTimeOut()) {
break;
}
product = product.multiply(new BigInteger(String.valueOf(num)));
}
mThreadsCOmputationResults[threadIndex] = product;
mNumOfFinishedThreads.incrementAndGet();
}).start();
}
}
private boolean isTimeOut() {
return System.currentTimeMillis() >= mComputationTimeoutTime;
}
private void initComputationParams(int argument, int timeOut) {
mNumberOfThreads = argument < 20 ? 1 : Runtime.getRuntime().availableProcessors();
mNumOfFinishedThreads.set(0);
mAbortComputation = false;
mThreadsCOmputationResults = new BigInteger[mNumberOfThreads];
mThreadsComputationRanges = new ComputationRange[mNumberOfThreads];
initThreadComputationRanges(argument);
mComputationTimeoutTime = System.currentTimeMillis() + timeOut;
}
private void initThreadComputationRanges(int argument) {
int computationRangeSize = argument / mNumberOfThreads;
long nextComputationRangeEnd = argument;
for(int i = mNumberOfThreads -1; i > 0; i--) {
mThreadsComputationRanges[i] = new ComputationRange(
nextComputationRangeEnd - computationRangeSize + 1,
nextComputationRangeEnd
);
nextComputationRangeEnd = mThreadsComputationRanges[i].start -1;
}
mThreadsComputationRanges[0].start = 1;
}
@Override
protected String getScreenTitle() {
return "Exercise 4";
}
@Override
public void onStop() {
super.onStop();
mAbortComputation = true;
}
private int getTimeOut() {
int timeOut;
if(mEdTimeOut.getText().toString().isEmpty()) {
timeOut = MAX_TIMEOUT_MS;
} else {
timeOut = Integer.valueOf(mEdTimeOut.getText().toString());
if(timeOut > MAX_TIMEOUT_MS) {
timeOut = MAX_TIMEOUT_MS;
}
}
return timeOut;
}
private static class ComputationRange{ // This line returns Null
private long start;
private long end;
public ComputationRange(long start, long end) {
this.start = start;
this.end = end;
}
}
}
java.lang.NullPointerException: Attempt to write to field 'long com.multithread.exrecises.exercise4.Exercise4Fragment$ComputationRange.start' on a null object reference
at com.multithread.exrecises.exercise4.Exercise4Fragment$ComputationRange.access$502(Exercise4Fragment.java:237)
at com.multithread.exrecises.exercise4.Exercise4Fragment.initThreadComputationRanges(Exercise4Fragment.java:209)