我是Java的新手。我知道静态和非静态方法的概念。 我想知道是否可以使用类的非静态方法而不必创建对它的引用。
例如,对于我的程序,我使用Date对象,我需要在其中一个中获取昨天的日期。我知道一种可能的方式如下:
Calendar cal= Calendar.getInstance();
cal.add(Calendar.DATE,-1);
Date yesterdayDate = new Date();
yesterdayDate = cal.getTime();
有没有办法做到这一点,而不必创建我将在整个程序中只使用一次的cal
引用?
这样的事情(我知道这绝不是正确的语法):
Date yesterdayDate = new Date();
yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime();
答案 0 :(得分:10)
如果Calendar
遵循流畅的构建器模式,即add
方法正在添加,那么返回变异的实例,您将能够。
你不是,因为Calendar#add
会返回void
。
但不要被愚弄:Calendar.getInstance()
确实按照指示创建实例 - 您只是不将其分配给引用。
答案 1 :(得分:2)
您所指的是已知的Builder
模式。
Calendar
类不是为了支持构建器模式而构建的,但是它还有许多其他类/ apis。
例如,来自joda time的DateTimeFormatterBuilder。
DateTimeFormatter monthAndYear = new DateTimeFormatterBuilder()
.appendMonthOfYearText()
.appendLiteral(' ')
.appendYear(4, 4)
.toFormatter();
您可以随时继续创建自己的构建器。 (在您的示例中,CalendarBuilder
)。
但是你应该知道Calendar类通常被认为是 evil - 它不是线程安全的。更新的选择是joda时间和java 8 api。
答案 2 :(得分:1)
如果方法返回类型是任何类的实例,则应对其进行链接调用,而不需要创建命名变量。
这在Fluent接口api中使用,其中每个方法都返回"这个"的实例。类。
注意: 如果在不同的对象上调用许多链式方法,请注意:
collection.get(0).getAddress()getStreet()长度();
因为可能存在NullPointerExceptions。
另一方面,使用流畅的api应该是安全的,因为你总是把它叫做#34;这个"例如,如果api没有一些奇怪的错误,它是安全的,不应该发生NPE。
答案 3 :(得分:0)
其他答案都是正确的,但我认为他们错过了一个关键点:如果你是Java的新手......不要浪费你的时间思考这些问题。
不要误解我的意思:了解你正在使用的编程语言总是很好;并且有一些常识可以避免"真正愚蠢的表现"错误。但是:不要担心"表现"花了几个小时来减少程序处理的对象数量......从100到95.这完全是浪费时间。
如果您打算编写长时间使用的程序,并且由多个人编写程序(而且#34;好的"程序往往会很快到达那里),那么它就是更重要的是您的程序易于阅读,理解和更改。
唯一有效的理由来调查"性能"是:
换句话说:不要试图解决"不存在"问题。除非您的应用程序在嵌入式环境中运行,其中每个内存字节和每个CPU周期都可以获得某个奖励...不要担心创建这些Calendar对象10,100或500次。
答案 4 :(得分:0)
一般的答案是否定的,因为像Calendar这样的类是有状态的,因此需要初始化的实例才能运行。如果你这样做:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE,-1);
您首先调用工厂方法getInstance()
来创建GregorianCalendar的实例,这是Calendar的默认具体实现。它被初始化为默认时区和语言环境,并设置为当前系统时间。这意味着它与您在几毫秒后创建的另一个实例不同。
然后,在您的实例上调用add(...)
或其他操作方法会影响日历状态,遵循编程的日历逻辑。如果这不是一个离散的实例而是全局(静态)状态,则多个线程会相互干扰并导致非常混乱的结果。
同样适用于SimpleDateFormat类。它通常被错误地设置为字段并重新用于在多线程上下文中格式化日期(例如,servlet的handle
方法)。这将导致不稳定的行为,因为SimpleDateFormat也是有状态的。
所以结论是:你需要创建像Calendar和SimpleDateFormat这样的类的独立实例,因为它们是有状态的,因此不是线程安全的。
请记住,有时您可以通过在执行任何迭代之前声明您的实例来优化一点,然后重新设置其状态,而不是在每次迭代时创建一个新实例(毕竟,创建Calendar的实例是确实有点贵。)
答案 5 :(得分:0)
这不仅仅是因为方法不是静态的。了解您不能这样链接 - yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime();
因为add()
方法不会返回任何内容。如果该方法会返回相同日历对象,则可以在不创建引用的情况下对其进行链接。
为了理解链接是如何工作的,你可以尝试创建自己的方法,返回对象并调用其他方法。