使用 NON static class 方法没有引用
Using NON static class Methods Without reference
我是 Java 的新手。我知道静态和非静态方法的概念。
我想知道是否可以使用 class 的非静态方法而不必创建对它的引用。
例如,对于我的程序,我正在使用 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();
如果 Calendar
遵循流畅的构建器模式,即 add
方法正在添加,然后返回变异的实例,您将能够。
你不是,因为 Calendar#add
returns void
.
但不要被愚弄:Calendar.getInstance()
确实 创建了一个实例 - 您只是没有将其分配给引用。
您指的是已知的 Builder
模式。
Calendar
class 不是为支持构建器模式而构建的,但是还有许多其他 classes / apis 在那里。
例如,DateTimeFormatterBuilder 来自 joda 时间。
DateTimeFormatter monthAndYear = new DateTimeFormatterBuilder()
.appendMonthOfYearText()
.appendLiteral(' ')
.appendYear(4, 4)
.toFormatter();
您可以随时创建自己的构建器。 (在您的示例中,CalendarBuilder
)。
但是您应该知道日历 class 通常被认为是 邪恶的 - 一方面,它不是线程安全的。较新的替代品是 joda time 和 java 8 api's.
如果方法 return 类型是任何 class 的实例,您应该对其进行链式调用,并且不需要创建命名变量。
这在 Fluent 界面 api 中使用,其中 "this" class.
的每个方法 returns 实例
注意:
如果您在不同的对象上调用许多链式方法,请小心,例如:
collection.get(0).getAddress().getStreet().length();
因为可能出现 NullPointerExceptions。
另一方面,使用 fluent api 应该是安全的,因为你总是在 "this" 实例上调用它,所以如果 api 没有一些奇怪的错误,它是安全且 NPE 不应发生。
其他答案都正确,但我认为他们遗漏了一个关键点:如果您是 Java 的新手...请不要浪费时间思考这些问题。
不要误会我的意思:深入了解您正在使用的编程语言总是好的;掌握一些常识以避免 "really stupid performance" 错误也很重要。
但是:不要担心 "performance" 并花费数小时来减少程序正在处理的对象数量...从 100 减少到 95。这完全是浪费时间。
如果您打算编写使用时间较长且被多人使用的程序(并且 "good" 程序往往会很快到达那里)那么 更重要的是您的程序易于阅读、理解和更改。
调查 "performance" 的唯一 有效 理由是:
- 您正处于设计阶段;并且如前所述,应该避免因性能问题而导致最终产品呈现 "unusable" 的愚蠢错误。
- 您实际上遇到了 "performance" 问题。然后你应该开始分析你的应用程序;然后,根据该分析改进 "slow" 部分。
换句话说:不要试图解决 "non-existing" 问题。除非您的应用程序 运行 处于嵌入式环境中,在这种环境中,每个内存字节和每个 CPU 周期都可以获得一定的奖励……不要担心创建那些 Calendar 对象 10、100 或 500次。
一般答案是否定的,因为 class像 Calendar 这样的东西是有状态的,因此需要一个初始化的实例才能运行。如果你这样做:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE,-1);
您首先调用工厂方法 getInstance()
来创建 GregorianCalendar 的实例,这是 Calendar 的默认具体实现。它被初始化为默认时区和语言环境,并设置为当前系统时间。这意味着它与您在几毫秒后创建的另一个实例不同。
然后,按照编程的日历逻辑,在您的实例上调用 add(...)
或其他操作方法会影响日历状态。如果这不是离散实例而是全局(静态)状态,多个线程将相互干扰并导致非常混乱的结果。
例如 SimpleDateFormat class 也是如此。它经常被错误地设置为一个字段,并在多线程上下文中重新用于格式化日期(例如 servlet 的 handle
方法)。这有时会导致不稳定的行为,因为 SimpleDateFormat 也是有状态的。
所以结论是:您需要创建 classes 的独立实例,例如 Calendar 和 SimpleDateFormat,因为它们是有状态的,因此不是线程安全的。
请记住,有时您可以通过在进行的任何迭代之前声明您的实例来进行一些优化,然后重新设置其状态,而不是在每次迭代时都创建一个新实例(毕竟,创建一个实例日历确实有点贵)。
不仅仅是因为方法不是静态的。明白你不能像这样链接 - yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime();
因为 add()
方法没有 return 任何东西。如果该方法会 return 为您提供 相同的 日历对象,您可以将它们链接起来而无需创建引用。
为了了解链接的工作原理,您可以尝试创建自己的 return 对象方法并调用它们的其他方法。
我是 Java 的新手。我知道静态和非静态方法的概念。 我想知道是否可以使用 class 的非静态方法而不必创建对它的引用。
例如,对于我的程序,我正在使用 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();
如果 Calendar
遵循流畅的构建器模式,即 add
方法正在添加,然后返回变异的实例,您将能够。
你不是,因为 Calendar#add
returns void
.
但不要被愚弄:Calendar.getInstance()
确实 创建了一个实例 - 您只是没有将其分配给引用。
您指的是已知的 Builder
模式。
Calendar
class 不是为支持构建器模式而构建的,但是还有许多其他 classes / apis 在那里。
例如,DateTimeFormatterBuilder 来自 joda 时间。
DateTimeFormatter monthAndYear = new DateTimeFormatterBuilder()
.appendMonthOfYearText()
.appendLiteral(' ')
.appendYear(4, 4)
.toFormatter();
您可以随时创建自己的构建器。 (在您的示例中,CalendarBuilder
)。
但是您应该知道日历 class 通常被认为是 邪恶的 - 一方面,它不是线程安全的。较新的替代品是 joda time 和 java 8 api's.
如果方法 return 类型是任何 class 的实例,您应该对其进行链式调用,并且不需要创建命名变量。
这在 Fluent 界面 api 中使用,其中 "this" class.
的每个方法 returns 实例注意: 如果您在不同的对象上调用许多链式方法,请小心,例如:
collection.get(0).getAddress().getStreet().length();
因为可能出现 NullPointerExceptions。
另一方面,使用 fluent api 应该是安全的,因为你总是在 "this" 实例上调用它,所以如果 api 没有一些奇怪的错误,它是安全且 NPE 不应发生。
其他答案都正确,但我认为他们遗漏了一个关键点:如果您是 Java 的新手...请不要浪费时间思考这些问题。
不要误会我的意思:深入了解您正在使用的编程语言总是好的;掌握一些常识以避免 "really stupid performance" 错误也很重要。
但是:不要担心 "performance" 并花费数小时来减少程序正在处理的对象数量...从 100 减少到 95。这完全是浪费时间。
如果您打算编写使用时间较长且被多人使用的程序(并且 "good" 程序往往会很快到达那里)那么 更重要的是您的程序易于阅读、理解和更改。
调查 "performance" 的唯一 有效 理由是:
- 您正处于设计阶段;并且如前所述,应该避免因性能问题而导致最终产品呈现 "unusable" 的愚蠢错误。
- 您实际上遇到了 "performance" 问题。然后你应该开始分析你的应用程序;然后,根据该分析改进 "slow" 部分。
换句话说:不要试图解决 "non-existing" 问题。除非您的应用程序 运行 处于嵌入式环境中,在这种环境中,每个内存字节和每个 CPU 周期都可以获得一定的奖励……不要担心创建那些 Calendar 对象 10、100 或 500次。
一般答案是否定的,因为 class像 Calendar 这样的东西是有状态的,因此需要一个初始化的实例才能运行。如果你这样做:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE,-1);
您首先调用工厂方法 getInstance()
来创建 GregorianCalendar 的实例,这是 Calendar 的默认具体实现。它被初始化为默认时区和语言环境,并设置为当前系统时间。这意味着它与您在几毫秒后创建的另一个实例不同。
然后,按照编程的日历逻辑,在您的实例上调用 add(...)
或其他操作方法会影响日历状态。如果这不是离散实例而是全局(静态)状态,多个线程将相互干扰并导致非常混乱的结果。
例如 SimpleDateFormat class 也是如此。它经常被错误地设置为一个字段,并在多线程上下文中重新用于格式化日期(例如 servlet 的 handle
方法)。这有时会导致不稳定的行为,因为 SimpleDateFormat 也是有状态的。
所以结论是:您需要创建 classes 的独立实例,例如 Calendar 和 SimpleDateFormat,因为它们是有状态的,因此不是线程安全的。
请记住,有时您可以通过在进行的任何迭代之前声明您的实例来进行一些优化,然后重新设置其状态,而不是在每次迭代时都创建一个新实例(毕竟,创建一个实例日历确实有点贵)。
不仅仅是因为方法不是静态的。明白你不能像这样链接 - yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime();
因为 add()
方法没有 return 任何东西。如果该方法会 return 为您提供 相同的 日历对象,您可以将它们链接起来而无需创建引用。
为了了解链接的工作原理,您可以尝试创建自己的 return 对象方法并调用它们的其他方法。