Java 什么是一致构造函数?

Java 什么是一致构造函数?,java,constructor,overloading,constructor-overloading,Java,Constructor,Overloading,Constructor Overloading,在进行构造函数重载时,我遇到了一种称为“一致构造函数”的东西。我理解构造函数重载的含义 Class Person { String Name; String City; Person(String N,String C) { Name=N; City=C; } Person(String N) { this(N,NULL); } } Class NewClass { public static void main(String[]

在进行构造函数重载时,我遇到了一种称为“一致构造函数”的东西。我理解构造函数重载的含义

Class Person
{
  String Name;
  String City;

  Person(String N,String C)
  {
    Name=N;
    City=C;
  }

  Person(String N)
  {
    this(N,NULL);
  }
}

Class NewClass
{
  public static void main(String[] args)
  {
    Person obj1=new Person("carl","max");
    Person obj2=new Person("Tommy");
  }
}

在我看来,什么是一致的构造函数:它使用
这个
,正如我在其中一个构造函数中所示,用于初始化实例变量。。。。在我的示例中,总是调用具有两个参数的构造函数


  • Java中的这些一致构造函数是什么

  • 这些技术的实际应用是什么

  • 为什么在Java中使用它们

  • 关于理解这个主题还有更多的信息吗


  • 有没有人能用外行的术语为我这样的noob提供更多关于这个主题的解释,以及更多关于这个主题的信息?

    我从来没有听说过它被称为“一致构造函数”。我想我听说过它叫“链式构造函数调用”。当您使用一个构造函数中的
    this
    关键字调用另一个构造函数时

    这些技术的实际应用是什么

    它们减少了代码重复,从而提高了可维护性。假设“Name=N”代码在每个构造函数中都是重复的:

    Person(String N,String C)
    {
      Name=N;
      City=C;
    }
    
    Person(String N)
    {
      Name=N;
      City=null;
    }
    
    现在假设我们要验证名称:

    Person(String N,String C)
    {
      if (N == null || N.length() == 0) throw new IllegalArgumentException();
      Name=N;
      City=C;
    }
    
    Person(String N)
    {
      Name=N;
      City=null;
    }
    
    我们更改了一个构造函数,但忘记了另一个,因此可以绕过对名称的限制。如果类非常复杂,这是一个真正的风险

    通过执行
    this(N,null)
    要从一个构造函数调用另一个构造函数,构造函数的主逻辑可以只在一个地方维护,即

    为什么在Java中使用它们

    与其他一些语言不同,Java不支持可选参数。在某些语言中,您可以这样编写构造函数:

    Person(String N, String C=null) {
      Name=N;
      City=C;
    }
    

    在这种情况下,只有一个构造函数,可以使用1或2个参数调用,如果未指定,city将默认为null。这不是有效的Java,但是可以通过重载来伪造它。

    我从来没有听说过它被称为“一致构造函数”。我想我听说过它叫“链式构造函数调用”。当您使用一个构造函数中的
    this
    关键字调用另一个构造函数时

    这些技术的实际应用是什么

    它们减少了代码重复,从而提高了可维护性。假设“Name=N”代码在每个构造函数中都是重复的:

    Person(String N,String C)
    {
      Name=N;
      City=C;
    }
    
    Person(String N)
    {
      Name=N;
      City=null;
    }
    
    现在假设我们要验证名称:

    Person(String N,String C)
    {
      if (N == null || N.length() == 0) throw new IllegalArgumentException();
      Name=N;
      City=C;
    }
    
    Person(String N)
    {
      Name=N;
      City=null;
    }
    
    我们更改了一个构造函数,但忘记了另一个,因此可以绕过对名称的限制。如果类非常复杂,这是一个真正的风险

    通过执行
    this(N,null)
    要从一个构造函数调用另一个构造函数,构造函数的主逻辑可以只在一个地方维护,即

    为什么在Java中使用它们

    与其他一些语言不同,Java不支持可选参数。在某些语言中,您可以这样编写构造函数:

    Person(String N, String C=null) {
      Name=N;
      City=C;
    }
    

    在这种情况下,只有一个构造函数,可以使用1或2个参数调用,如果未指定,city将默认为null。这不是有效的Java,但可以通过重载来伪造它。

    这是我经常使用的一种很好的技术,但我不知道它的名称。它还可以应用于重载方法。主要的好处是,您可以为多个输入案例提供单一逻辑,并提供默认值以简化其使用。即,您有一个具有完整签名的方法,如:

    foo(a, b, c, d) {...}
    
    而且相当长。这可能是一种代码味道,也就是说,最好将这些参数组合成一个或两个参数对象或实例状态。无论如何,拥有此签名可能是有原因的,因此为了简化此方法的使用,可以提供一个使用默认值调用它的签名:

    foo(a, b){
        return foo(a, b, defaultC, defaultD);
    }
    
    反格

    您有一个要参数化的方法
    foo(a)

    foo(name){
        System.out.println("Hello, " + name);
    }
    
    您需要将
    “Hello,”
    作为一个参数传递给单个案例。如果这是一个真正的项目,并且在其他100个地方使用了
    foo
    ,您可以这样做:

    foo(a){
        foo("Hello", a);
    }
    
    foo(greeting, name){
        System.out.println(greeting +", " + name);
    }
    

    一些IDE支持这种重构,因此这是一种非常方便的技术。

    这是我经常使用的一种很好的技术,但我不知道它的名称。它还可以应用于重载方法。主要的好处是,您可以为多个输入案例提供单一逻辑,并提供默认值以简化其使用。即,您有一个具有完整签名的方法,如:

    foo(a, b, c, d) {...}
    
    而且相当长。这可能是一种代码味道,也就是说,最好将这些参数组合成一个或两个参数对象或实例状态。无论如何,拥有此签名可能是有原因的,因此为了简化此方法的使用,可以提供一个使用默认值调用它的签名:

    foo(a, b){
        return foo(a, b, defaultC, defaultD);
    }
    
    反格

    您有一个要参数化的方法
    foo(a)

    foo(name){
        System.out.println("Hello, " + name);
    }
    
    您需要将
    “Hello,”
    作为一个参数传递给单个案例。如果这是一个真正的项目,并且在其他100个地方使用了
    foo
    ,您可以这样做:

    foo(a){
        foo("Hello", a);
    }
    
    foo(greeting, name){
        System.out.println(greeting +", " + name);
    }
    
    一些IDE支持将其作为重构,因此这是一种非常方便的技术。

    我从来没有听说过一致构造函数,但我猜它是关于由不同构造函数初始化的参数。让我们看看不一致的构造函数可能是什么样子的:

    class Person {
        String firstName;
        String lastName;
        Integer age;
    
        Person(String firstName, String lastName, Integer age) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.age = age;
        }
    
        Person(String firstName, String lastName) {
            this(firstName, lastName, 0);
        }
    
        Person(String firstName) {
            this(firstName, null, null);
        }
    }
    
    Person p1 = new Person("Joe", "Doe", 24);
    Person p2 = new Person("Joe", "Doe");
    Person p3 = new Person("Joe");
    
    矛盾在哪里?您可能希望人名2和3的年龄(
    p2
    p3
    )未定义,即其值为
    -1
    0
    null
    )。只要使用
    Person(String,String)
    Person(String
    将为您提供非常相同的一致的值,那么使用哪一个值并不重要

    在本例中,第二个构造函数将
    age
    初始化为
    0
    ,但第三个构造函数将此属性初始化为
    nul