简体   繁体   English

调用其他方法和不可变实例

[英]Calling other methods and immutable instances

This is a question from an exam past paper. 这是过去考试的一个问题。 I have completed the question and it works. 我已经完成了问题,并且可以解决问题。 However, i feel my implementation may be weak eg my use of static throughout the Gregorian class. 但是,我觉得我的实现可能很薄弱,例如我在整个Gregorian类中都使用static。

I was given three methods to write in any way i saw fit (in the Gregorian class) given a scenario for each. 在给定每种情况的情况下,我有3种方法可以按照我认为合适的方式(在Gregorian类中)进行编写。 Was I right in using static on the three methods in the Gregorian class. 我在Gregorian类的三种方法上使用static方法是正确的吗?

Also the day, month and year fields are meant to be immutable, is setting them as private enough? 另外,day,month和year字段是不可变的,是否将它们设置为足够私有? (once they are created the field values cannot be changed) (一旦创建,则不能更改字段值)

public class Date {

private int day;// needs to be immutable?
private String month;// needs to be immutable?
private int year;// needs to be immutable?

public Date(int theDay, String theMonth, int theYear) {
    this.day = theDay;
    this.month = theMonth;
    this.year = theYear;
}

public int getDay() {
    return day;
}

public String getMonth() {
    return month;
}

public int getYear() {
    return year;
}

}

public class Gregorian {

public static Date d;

public static boolean leapYear(){

    if(d.getYear() %400==0 || (d.getYear()%4==0 && d.getYear()%100!=0)){
        return true;
    }else{
        return false;
    }
}

public static int getGregorianDateNumber(){
    int a = (d.getYear()*384)*(32+d.getDay());
    return a;
}

public static int getISO8601Date(){
    int b = (d.getYear()*367)+d.getDay();
    return b;
}

public static void main (String[] args){
    d = new Date(9, "June", 8);
    System.out.println(getGregorianDateNumber());
    System.out.println(getISO8601Date());
    System.out.println(leapYear());
}

}

Instead of the static methods and the static field d make them all non-static. 取而代之的是静态方法和静态字段d它们全部都是非静态的。

public class Gregorian {
    private final Date d;

    public Gregorian(Date d_) {
        this.d = d_;
    }

    public boolean isLeapyear() {
        ... // implemented as above
    }

    ... // Other methods as above, but all non-static.
}

And main as follows: 主要内容如下:

public static void main (String[] args){
    Date d = new Date(9, "June", 8);
    Gregorian g = new Gregorian(d);
    System.out.println(g.getGregorianDateNumber());
    System.out.println(g.getISO8601Date());
    System.out.println(g.leapYear());
}

Strings are by default immutable. 默认情况下,字符串是不可变的。

private int day;// needs to be immutable?
private int year;// needs to

are not immutable fields as you defined. 不是您定义的不可变字段。 Their state can change. 他们的状态可以改变。 Make them final. 使其最终。

NOTE: Making a reference final doesn't mean object state can't be changed (In your case this note is irrelevant, because you are not referencing objects). 注意:将引用定为final并不意味着不能更改对象状态(在您的情况下,此注释无关紧要,因为您没有引用对象)。

I'll agree with thinksteep - adding "final" to your fields will help keep them from being changed. 我会同意thinksteep的观点-向您的字段添加“ final”将有助于防止更改它们。 Not having setters reinforces this. 没有二传手会加强这一点。

In addition, I want to point out that 另外,我想指出一点

private String month;// needs to be immutable?

can be created as anything, from "January" to "Pie". 可以创建为从“一月”到“派”的任何内容。 If I may suggest, change it to an enum and establish the allowed values for months. 如果我建议,请将其更改为一个枚举,并确定允许的值数月。

public enum MonthName {
    JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC;
}

Change your Date class to the following: 将您的Date类更改为以下内容:

private final int day;
private final MonthName month;
private final int year;

public Date(int theDay, MonthName theMonth, int theYear) {
    this.day = theDay;
    this.month = theMonth;
    this.year = theYear;
}

both day and year are primitives and There is already immutable version of int available which is Integer you can make use of that. dayyear都是原语,并且已经有不可变的int版本,可以使用Integer

Second thing is, rather having a static reference to Date in Gregorian , pass the Date as an argument to each of the static methods. 第二件事是,而不是在Gregorian静态引用Date ,将Date作为参数传递给每个static方法。 You can assure the thread safety then. 您可以确保线程安全。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM