gpt4 book ai didi

java - 在构造函数退出之前访问最终变量

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:52:30 25 4
gpt4 key购买 nike

好吧,我一直在摆弄出色的 JodaTime 库,试图实现一般情况下的零售/财政 (4-5-4) 日历。我已经为我的公司找到了具体案例,但一般案例(主要是确定年初和闰年)是致命的;例如,有一组日期,其中两个会计年度(通常为 364 天)将在 1 个 ISO 年度内开始。

在确定年份开始规则的过程中,我最终得到了一个抽象类和几个具体类,用于根据它们落在 ISO 闰日的哪一侧来确定年份开始。

(精简)抽象类:

private static abstract class SimpleFiscalYearEndPattern implements FiscalYearEndPattern {

protected final int leapYearCountOffset;
protected final int doomsdayOffset;

private final int startingDayOfWeek;
private final int yearOffset;
private final long millisFromEpochToFiscalYearStart;
private final long millisElapsedToEpochDividedByTwo;

/**
* Restricted constructor
* @param fiscalYear
* @param startingOn
* @param inFirstWeek
*/
protected SimpleFiscalYearEndPattern(final int fiscalYear, final LocalDate startingOn, final MonthDay inFirstWeek) {
this.yearOffset = fiscalYear - startingOn.getYear();
this.doomsdayOffset = getDoomsdayOffset(inFirstWeek);
this.startingDayOfWeek = startingOn.getDayOfWeek();

final int startingDoomsday = getDoomsdayOffset(new MonthDay(startingOn, REFERENCE_CHRONOLOGY));
// If the starting doomsday is a later day-of-week, it needs to become negative.
this.leapYearCountOffset = calculateLeapYearCountOffset(startingDoomsday : doomsdayOffset, doomsdayOffset);

final int leapYearsBefore = getPreviousLeapYears(fiscalYearBeforeEpoch);
}
}

(精简)具体类(适用于 1/7 - 2/28 范围内的日期):

private static final class BeforeLeapYearEndPattern extends SimpleFiscalYearEndPattern {

private static final int FIRST_YEAR_LEAP_YEAR_OFFSET = -1;

private BeforeLeapYearEndPattern(final int fiscalYear, final LocalDate startingOn, final MonthDay onOrBefore) {
super(fiscalYear, startingOn, onOrBefore);
}

public static final BeforeLeapYearEndPattern create(final int fiscalYear, final LocalDate startingOn, final MonthDay onOrBefore) {
return new BeforeLeapYearEndPattern(fiscalYear, startingOn, onOrBefore);
}

/* (non-Javadoc)
* @see ext.site.time.chrono.FiscalYearEndPatternBuilder.SimpleFiscalYearEndPattern#getPreviousLeapYears(int)
*/
@Override
protected int getPreviousLeapYears(final int isoYear) {
// Formula gets count of leap years, including current, so subtract a year first.
final int previousYear = isoYear - 1;
// If the doomsday offset is -1, then the first year is a leap year.
return (previousYear + leapYearCountOffset + (previousYear / 4) - (previousYear / 100) + (previousYear / 400)) / 7 + (leapYearCountOffset == FIRST_YEAR_LEAP_YEAR_OFFSET ? 1 : 0);
}

如果您注意到,我使用了 leapYearCountOffset,它在抽象父类(super class)中定义(作为最终变量),在 getPreviousLeapYears() 中,然后从父类(super class)构造函数中调用。我不想在父类(super class)构造函数中重复公式 - 对于 3/1-12/31 范围内的日期是不同的;我也不想将实例变量放在具体的子类中 - 其他计算仍然需要 leapYearCountOffset

问题是从构造函数调用(子类)方法时leapYearCountOffset 的状态是什么?它是否以任何方式得到保证,或者是否可以随编译器的心血来潮而改变?我到底该如何测试才能找到答案?我已经知道编译器可以自由地重新安排一些语句,但是会(可能吗?)会在这里发生吗?

最佳答案

final 变量的保证之一是编译器不会让您在分配它们之前访问它们。所以,如果它编译(它应该编译),你就可以开始了!

关于java - 在构造函数退出之前访问最终变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10129468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com