Java中向Calendar对象添加时间后数组未达预期值的问题咨询
问题分析与解决方案
嘿,这个坑我当初刚学Java的时候也踩过!核心问题出在你对Java引用类型的理解上,Calendar是典型的引用类型,不是int那种值类型,直接赋值只会传递对象的引用,而不是复制整个对象。
为什么输出不符合预期?
你只创建了一个Calendar begin对象,然后在循环里反复把它的引用赋值给数组的times[i][0]和times[i][1]——也就是说,数组里所有的元素其实都指向同一个Calendar实例!
每次调用begin.add(Calendar.MINUTE, 120)时,都是在修改这个唯一的Calendar对象的状态。到循环结束时,所有数组元素引用的都是最后一次add操作后的那个对象,所以输出的所有开始和结束时间都会是同一个值。
举个简单的类比:你有一个笔记本,把它的地址写在了10张纸条上(数组元素),每次你在笔记本上改内容,所有纸条指向的都是这本被改后的笔记本,而不是10本不同的笔记本。
怎么修复?
你需要在每次循环时复制一个新的Calendar对象,而不是复用同一个引用。可以用clone()方法来复制当前状态的Calendar:
public static void main(String[] args) { Calendar[][] times = new Calendar[10][2]; Calendar begin = Calendar.getInstance(); for(int i = 0; i < 10; i++) { times[i][0] = (Calendar) begin.clone(); // 复制当前begin的状态到新对象 begin.add(Calendar.MINUTE, 120); times[i][1] = (Calendar) begin.clone(); // 再复制修改后的状态 } for(int i = 0; i < 10; i++) { System.out.println("Start time:" + times[i][0].getTime() + " and end time is: " + times[i][1].getTime()); } }
额外推荐:使用Java 8+的日期API
其实Java 8之后推出的java.time包(比如LocalDateTime、Duration)是不可变类型,调用修改方法时会返回新的对象,从根源上避免了这种引用问题,代码也更简洁:
import java.time.LocalDateTime; public static void main(String[] args) { LocalDateTime[][] times = new LocalDateTime[10][2]; LocalDateTime begin = LocalDateTime.now(); for (int i = 0; i < 10; i++) { times[i][0] = begin; begin = begin.plusMinutes(120); // plus方法返回新对象,原begin不变 times[i][1] = begin; } for (int i = 0; i < 10; i++) { System.out.println("Start time:" + times[i][0] + " and end time is: " + times[i][1]); } }
内容的提问来源于stack exchange,提问作者itsgreylolol
相关产品推荐
相关产品推荐

