【问题标题】:Initializing private variables inside a constructor在构造函数中初始化私有变量
【发布时间】:2011-02-21 20:56:25
【问题描述】:

我一直在查看此代码作为比较器。我的问题是在构造函数中初始化两个私有变量有一个特定的好处(在默认构造函数中完成)。我知道第二个构造函数可用于创建具有提供值的实例。如果我这样做会有什么不同

private String sortBy = COLUMN_LAST_NAME;
private boolean ascending = true; 

如果这是一个真正简单而笼统的问题,我深表歉意。

public class CustomComparator implements Comparator<StudentList>
{   private String sortBy;
private boolean ascending;

public CustomComparator()
{
    sortBy = COLUMN_LAST_NAME;
    ascending = true;
}

public CustomComparator(String sortBy, boolean ascending)
{
    this.sortBy = sortBy;
    this.ascending = ascending;
}

【问题讨论】:

    标签: java variables initialization


    【解决方案1】:

    我在各处看到的最佳实践是拥有一个接受所有参数的构造函数,即使这意味着它必须是私有的,然后只需使用this(..,..,...) 从其他构造函数调用它,同时提供适当的值。

    这将使您尽可能多地重用代码,并且未来的修复只在一个地方进行 - 无需对代码进行双重维护。

    您的示例如下所示:

    public class CustomComparator implements Comparator<StudentList> {
        private String sortBy;
        private boolean ascending;
    
        public CustomComparator()
        {
            this(COLUMN_LAST_NAME, true);
        }
    
        public CustomComparator(String sortBy, boolean ascending)
        {
            this.sortBy = sortBy;
            this.ascending = ascending;
        }
    }
    

    初始化通常被认为是在构造函数中,以便更容易区分静态成员的静态初始化和实例变量的每个实例初始化。没有性能差异。

    【讨论】:

    • 如果您不想在初始化私有变量时弄乱您的构造函数,例如因为它们独立于外部代码(假设 sortBy 已经初始化为与使用的构造函数无关的相同值)并且它们不能在短的一行中分配,你可以使用初始化块。
    【解决方案2】:

    实际上,如果您关心对象的不变性,这很重要(而且您应该 :-))。如果你的两个字段都是final,你必须像这样初始化它们:

    public class CustomComparator implements Comparator<StudentList> {
        private final String sortBy;
        private final boolean ascending;
    
        public CustomComparator() {
            sortBy = COLUMN_LAST_NAME;
            ascending = true;
        }
    
        public CustomComparator(String sortBy, boolean ascending) {
            this.sortBy = sortBy;
            this.ascending = ascending;
        }
    }
    

    甚至更好:

    public class CustomComparator implements Comparator<StudentList> {
        private final String sortBy;
        private final boolean ascending;
    
        public CustomComparator() {
            this(COLUMN_LAST_NAME, true);
        }
    
        public CustomComparator(String sortBy, boolean ascending) {
            this.sortBy = sortBy;
            this.ascending = ascending;
        }
    }
    

    【讨论】:

    • 感谢 Tomasz,如果我做私有最终布尔升序 = true;在构造函数之外,这将如何影响对象的不变性?
    • @t0mcat 到了参数构造函数根本不能用的地步。
    • @t0mcat:因为一旦分配了final 值,就不能在构造函数或任何其他地方更改(仅一次语义)
    • final 字段只能分配一次。如果您在构造函数之外分配值,则无法分配任何新值。想想像照片这样的最终字段,你不能分配任何新值
    • @ Franco,@ Tomasz .. 谢谢 :)
    【解决方案3】:

    这完全取决于您的需求,两个构造函数都是不错的选择,显然如果您想初始化字段是最好的选择,但是如果您像 Hibernate 上的实体或 Spring 框架上的 bean 一样使用此类,请考虑不要写空的构造函数,什么都不会运行良好......

    如果你在 DTO 模式中思考,声明像 @Tomasz Nurkiewicz 这样的不可变字段,那么参数化构造函数是唯一的选择......

    但就像我之前说的,这取决于要求...

    【讨论】:

      【解决方案4】:

      我想不出有什么区别,我更喜欢在变量声明中进行初始化。

      【讨论】:

      • 嗨 carlosZ,我是新手,所以即使是这些简单的声明也让我怀疑我是否遗漏了什么:-)
      猜你喜欢
      • 2011-03-18
      • 2020-09-27
      • 2015-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 2016-11-28
      相关资源
      最近更新 更多