问题描述
今天写bug代码的时候有一个List< Date >类型的集合在使用getTime()方法时出现了空指针异常,日志提示java.lang.NullPointerException: Attempt to invoke virtual method ‘long java.util.Date.getTime()’ on a null objectreference,本意是把一个活动中List< String >类型的时间集合直接用bundle传递给另一个活动HistoryActivity,再将类型转换为List< Date >使用,结果在接收的活动中使用Date.getTime()方法获取时间时一直报空指针。
代码
//传值的活动
Intent history=new Intent(MainActivity.this,HistoryActivity.class);
Bundle bundle = new Bundle() ;
bundle.putStringArrayList("DATA", history_times);
Log.d(TAG,"myhistorytimes"+history_times.toString());
history.putExtras(bundle) ;
startActivity(history) ;
//取值的活动
Intent intent = getIntent() ;
Bundle bundle=intent.getExtras();
ArrayList<String> recvData = new ArrayList<>();//收到的数据
if (bundle != null) {
recvData = (ArrayList<String>)bundle.getStringArrayList("DATA");
Log.d(TAG,"myhistorytimes"+recvData.toString());
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd/hh:mm:ss");//时间的格式
ParsePosition pos = new ParsePosition(0);
history_times.clear();
for (String aRecvData : recvData) {
Date strtodate = formatter.parse(aRecvData, pos);
history_times.add(strtodate);
}
Log.d(TAG,"onCreate myhistorytimes before"+history_times.toString());
//使用List<Date> history_times时报错
try {
if(history_times!=null){
Log.d(TAG,"myhistorytimes getLineData good "+history_times.toString());
for(Date d:history_times){
String time2 = new SimpleDateFormat("yyyy/MM/dd").format(d.getTime());
if(time1.equals(time2)){ //比较两个时间
value++;
section_count++;
}
}
xValues.add(time1);
yValues.add(new Entry(value, i));
}
}catch (Exception e) {
Log.d(TAG,"myhistorytimes getLineData bad "+data.toString());
Log.e(TAG,"myhistorytimes"+e.toString());
}
问题分析
从输出的log中可以发现我的数据在传之前有五个值,传到之后也有五个具体的值,但是在使用时五个值只有第一个有具体值,余下的都是null,在进入到HistoryActivity时直接闪退,用stackoverflow上的方法捕获异常之后代码可以正常运行不闪退,但是依然不能获取到正确的数据stackoverflow:Attempt to invoke virtual method ‘long java.util.Date.getTime()’ on a null objectreference
所以问题大概率是出在把List < String >类型转换为List < Date >时,只有第一个值成功加到了List < Date > history_time中。(到处加Log.d标签找了好久才找到问题所在,论Log的重要性)
问题求解
问题在于ParsePosition pos = new ParsePosition(0)这里,本来以为ParsePosition 像SimpleDateFormat 一样在前面声明和初始化之后,后面每个值都能共用他们,但是实际上ParsePosition对象相当于是一个索引参数记录当前位置,所以不同的对象在使用ParsePosition处理格式时都要重新new一个ParsePosition,不能共用。
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd/hh:mm:ss");//时间的格式
ParsePosition pos = new ParsePosition(0);
history_times.clear();
for (String aRecvData : recvData) {
Date strtodate = formatter.parse(aRecvData, pos);
history_times.add(strtodate);
}
ParsePosition类说明
所以应该把ParsePosition pos = new ParsePosition(0)放在for循环里面,对取到的每一个值都单独进行类型转换。
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd/hh:mm:ss");//时间的格式
history_times.clear();
for (String aRecvData : recvData) {
ParsePosition pos = new ParsePosition(0);
Date strtodate = formatter.parse(aRecvData, pos);
history_times.add(strtodate);
}
如图,不再报错,而且可以取到正确的值,问题得解。