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");
}
}
在我看来,什么是一致的构造函数:它使用
这个
,正如我在其中一个构造函数中所示,用于初始化实例变量。。。。在我的示例中,总是调用具有两个参数的构造函数
有没有人能用外行的术语为我这样的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