当我们创建一个对象时,该对象将具有类的数据成员和方法的引用。
For Eg: TestObject obj = new TestObject();
System.out.println("Test Object is:"+obj);
据我所知,新操作符的作用是,它为指定的类(变量和方法)创建/分配内存块,并将该引用分配给左侧变量(obj)。因此,上面的print语句打印了TestObject类的引用。
但是,我的问题是,当我们为Date类创建一个对象并打印该对象时,它会打印出今天的日期。
For eg: Date date = new Date();
System.out.println("Date Object is:"+date);
上面的代码打印出今天的日期。为什么以及如何打印日期而不是Date类引用。请帮帮我。
很抱歉,如果这是一个愚蠢的问题。即使这很愚蠢,我也没有这个问题的答案。
简要说明是可以理解的。
答案 0 :(得分:4)
当您在内部使用实例的引用进行打印时,它将被称为类的toString()
方法。在Date
类中,toString()
方法返回它包含的日期。
日期api's toString()
方法说,
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
如果您有意义地覆盖了类中的toString()
方法,那么将打印出来的任何返回值而不是参考内存值。
答案 1 :(得分:2)
由于toString()
中的Date
实施,请查看java.util.Date
源代码(指向openjdk7实施的链接)
Javadoc引用:
将此
Date
对象转换为以下格式的String
:dow mon dd hh:mm:ss zzz yyyy
答案 2 :(得分:1)
由于toString()
类的Date()
。
public String toString() {
// "EEE MMM dd HH:mm:ss zzz yyyy";
BaseCalendar.Date date = normalize();
StringBuilder sb = new StringBuilder(28);
int index = date.getDayOfWeek();
if (index == gcal.SUNDAY) {
index = 8;
}
convertToAbbr(sb, wtb[index]).append(' '); // EEE
convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
TimeZone zi = date.getZone();
if (zi != null) {
sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT,Locale.US));
// zzz
} else {
sb.append("GMT");
}
sb.append(' ').append(date.getYear()); // yyyy
return sb.toString();
}
答案 3 :(得分:1)
正如其他答案正确陈述的那样,Java中的所有类都有一个继承自超级父类toString
的Object
方法。
如果特定类的程序员选择不使用自己的实现覆盖toString
方法,则她的类继承默认实现。该默认实现输出您描述的变量引用信息。正如Object类doc所述,你有效地得到了这个......
getClass().getName() + '@' + Integer.toHexString(hashCode())
究竟应该对toString
的覆盖实施做些什么? Sun / Oracle文档说......
通常,toString方法返回一个“文本表示”此对象的字符串。结果应该是一个简洁但信息丰富的表示,便于人们阅读。建议所有子类都覆盖此方法。
许多程序员一直在讨论toString
中究竟应该实现的内容。问题是toString
用于各种情况。编程时,我们用System.out.println
调用该方法将值转储到控制台进行调试。另一个上下文是记录,在扩展测试期间记录值。或者我们可以在生产过程中进行此类记录另一个上下文是生成用于在消息或错误报告的用户界面中显示的字符串。
一些程序员认为对象应该有多种这样的方法,以适应这些不同的目的。但是在Java中,我们对每个对象都内置的是单个这样的方法toString
。用它做你想做的事。
java.util.Date类的设计者决定他们toString
的实现将获取Date的值,该Date实际上没有时区信息,然后应用JVM的默认时间区域以古怪的笨拙格式输出日期时间。
该格式的一个坏处是使用三个字母的时区代码。不幸的是,这些代码既不是标准化也不是唯一的,有一些常见的重复,如爱尔兰标准时间和印度标准时间的IST。避免使用这些3个字母的代码,而是使用proper time zone names。
关于java.util.Date的toString
最糟糕的事情是,它造成了一个令人困惑的印象,即如果事实上没有,则Date有一个时区。这种混乱在StackOverflow和其他地方创造了无穷无尽的重复问题。因此,java.util.Date是一个伟大的案例研究,介绍如何不编写toString
实现。
幸运的是,经过漫长的等待,旧的java.util.Date& java.util.Calendar类将被java.time.* package中的新Java 8取代。此程序包由JSR 310定义,受Joda-Time启发。
Joda-Time是捆绑的java.util.Date/Calendar类的流行替代品。 Joda-Time是一个开源的免费图书馆。
Joda-Time中DateTime
对象的实现使用基于ISO 8601格式的内置格式化程序。出于多种原因,ISO格式是一种很好的格式。一个原因是标准清晰准确。另一个是格式直观,无论文化规范如何,全球任何人都可以确定其含义。另一个好处是,作为一个没有空格的单个连续字符串使得在编程中处理和解析它更容易,尽管技术上中间的“T”是可选的(但强烈鼓励)。包含时区信息,但使用明确的小时和分钟偏移量而不是3个字母的代码。
总而言之,这是如何实施toString
的一个很好的例子。
java.util.Date date = new java.util.Date();
通常更好地指定时区而不是依赖默认值。
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" ); // Formerly known as Calcutta, India.
将该Date对象转换为Joda-Time DateTime对象。或者你可以从头开始创建一个新的DateTim。
DateTime dateTime_India = new DateTime( date, timeZone ); // Or… new DateTime( timeZone );
如果需要,您可以通过基于第一个实例创建另一个实例来转换为UTC / GMT(无时区偏移)。 Joda-Time通常遵循immutable object设计。生成一个新对象,类似于原始对象,但调整某些方面,如时区偏移。
DateTime dateTime_UtcGmt = dateTime_India.toDateTime( DateTimeZone.UTC );
转储到控制台,使用使用ISO 8601格式的内置formatter的“toString”的默认实现。知道Joda-Time提供了丰富的工具来输出日期时间的许多不同格式的字符串表示,但这里的重点是默认,即“toString”的实现。这些println
行中的每一行都隐式调用对象的toString
方法。
System.out.println( "date: " + date );
System.out.println( "timeZone: " + timeZone );
System.out.println( "dateTime_India: " + dateTime_India );
System.out.println( "dateTime_UtcGmt: " + dateTime_UtcGmt );
跑步时......
date: Thu Feb 06 00:17:19 PST 2014
timeZone: Asia/Kolkata
dateTime_India: 2014-02-06T13:47:19.796+05:30
dateTime_UtcGmt: 2014-02-06T08:17:19.796Z