是否可以从另一个(在同一个类中,而不是从子类中)调用构造函数?如果有,怎么样?什么是调用另一个构造函数的最佳方法(如果有几种方法可以做到)?
对的,这是可能的:
public class Foo { private int x; public Foo() { this(1); } public Foo(int x) { this.x = x; } }
要链接到特定的超类构造函数而不是同一个类中的一个,请使用super
而不是this
.请注意,您只能链接到一个构造函数,它必须是构造函数体中的第一个语句.
另请参阅此相关问题,该问题与 C#相关,但适用相同的原则.
用this(args)
.首选模式是从最小的构造函数到最大的构造函数.
public class Cons { public Cons() { // A no arguments constructor that sends default values to the largest this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value); } public Cons(int arg1, int arg2) { // An example of a partial constructor that uses the passed in arguments // and sends a hidden default value to the largest this(arg1,arg2, madeUpArg3Value); } // Largest constructor that does the work public Cons(int arg1, int arg2, int arg3) { this.arg1 = arg1; this.arg2 = arg2; this.arg3 = arg3; } }
您还可以使用最近提倡的valueOf或仅仅是"of"的方法:
public class Cons { public static Cons newCons(int arg1,...) { // This function is commonly called valueOf, like Integer.valueOf(..) // More recently called "of", like EnumSet.of(..) Cons c = new Cons(...); c.setArg1(....); return c; } }
要调用超类,请使用super(someValue)
.对super的调用必须是构造函数中的第一个调用,否则您将收到编译器错误.
[ 注意:我只想添加一个方面,我在其他答案中没有看到:如何克服这个()必须在第一行的要求的限制).]
在Java中,可以从构造函数中调用同一类的另一个构造函数this()
.但请注意,this
必须在第一行.
public class MyClass { public MyClass(double argument1, double argument2) { this(argument1, argument2, 0.0); } public MyClass(double argument1, double argument2, double argument3) { this.argument1 = argument1; this.argument2 = argument2; this.argument3 = argument3; } }
这this
必须出现在第一行看起来像一个很大的限制,但你可以通过静态方法构造其他构造函数的参数.例如:
public class MyClass { public MyClass(double argument1, double argument2) { this(argument1, argument2, getDefaultArg3(argument1, argument2)); } public MyClass(double argument1, double argument2, double argument3) { this.argument1 = argument1; this.argument2 = argument2; this.argument3 = argument3; } private static double getDefaultArg3(double argument1, double argument2) { double argument3 = 0; // Calculate argument3 here if you like. return argument3; } }
当我需要从代码内部调用另一个构造函数(而不是在第一行)时,我通常使用这样的辅助方法:
class MyClass { int field; MyClass() { init(0); } MyClass(int value) { if (value<0) { init(0); } else { init(value); } } void init(int x) { field = x; } }
但是大多数情况下,我尝试通过从第一行中较简单的构造函数调用更复杂的构造函数来反过来做到这一点.对于上面的例子
class MyClass { int field; MyClass(int value) { if (value<0) field = 0; else field = value; } MyClass() { this(0); } }
在构造函数中,您可以使用该this
关键字在同一个类中调用另一个构造函数.这样做称为显式构造函数调用.
这是另一个Rectangle类,其实现与Objects部分中的实现不同.
public class Rectangle { private int x, y; private int width, height; public Rectangle() { this(1, 1); } public Rectangle(int width, int height) { this( 0,0,width, height); } public Rectangle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } }
该类包含一组构造函数.每个构造函数都初始化一些或所有矩形的成员变量.
正如大家已经说过的那样,你使用了this(…)
,这被称为显式构造函数调用.
但是,请记住,在这样的显式构造函数调用语句中,您可能不会引用
任何实例变量或
任何实例方法或
在此类或任何超类中声明的任何内部类,或
this
要么
super
.
如JLS(§8.8.7.1)中所述.
是的,可以从另一个构建函数调用.但它有一个规则.如果从一个构造函数调用到另一个构造函数,那么
新的构造函数调用必须是当前构造函数中的第一个语句
public class Product { private int productId; private String productName; private double productPrice; private String category; public Product(int id, String name) { this(id,name,1.0); } public Product(int id, String name, double price) { this(id,name,price,"DEFAULT"); } public Product(int id,String name,double price, String category){ this.productId=id; this.productName=name; this.productPrice=price; this.category=category; } }
所以,像下面这样的东西是行不通的.
public Product(int id, String name, double price) { System.out.println("Calling constructor with price"); this(id,name,price,"DEFAULT"); }
此外,在继承的情况下,当创建子类的对象时,首先调用超类构造函数.
public class SuperClass { public SuperClass() { System.out.println("Inside super class constructor"); } } public class SubClass extends SuperClass { public SubClass () { //Even if we do not add, Java adds the call to super class's constructor like // super(); System.out.println("Inside sub class constructor"); } }
因此,在这种情况下,还会在任何其他语句之前声明另一个构造函数调用.
是的,任何数量的构造函数都可以存在于类中,并且可以使用this()
[请不要将this()
构造函数调用与this
关键字混淆] 由另一个构造函数调用它们.this()
或者this(args)
应该是构造函数中的第一行.
例:
Class Test { Test() { this(10); // calls the constructor with integer args, Test(int a) } Test(int a) { this(10.5); // call the constructor with double arg, Test(double a) } Test(double a) { System.out.println("I am a double arg constructor"); } }
这称为构造函数重载.
请注意,对于构造函数,只有重载概念适用,而不是继承或覆盖.
我会告诉你一个简单的方法
有两种类型的构造函数:
默认构造函数
参数化构造函数
我将在一个例子中解释
class ConstructorDemo { ConstructorDemo()//Default Constructor { System.out.println("D.constructor "); } ConstructorDemo(int k)//Parameterized constructor { this();//-------------(1) System.out.println("P.Constructor ="+k); } public static void main(String[] args) { //this(); error because "must be first statement in constructor new ConstructorDemo();//-------(2) ConstructorDemo g=new ConstructorDemo(3);---(3) } }
在上面的例子中,我展示了3种类型的呼叫
this()调用this必须是构造函数中的第一个语句
这是Name less Object.这会自动调用默认构造函数.3.这会调用参数化构造函数.
注意: 这必须是构造函数中的第一个语句.
您可以使用"this"关键字从同一个类的另一个构造函数构造一个构造函数.示例 -
class This1 { This1() { this("Hello"); System.out.println("Default constructor.."); } This1(int a) { this(); System.out.println("int as arg constructor.."); } This1(String s) { System.out.println("string as arg constructor.."); } public static void main(String args[]) { new This1(100); } }
输出 - 字符串作为arg构造函数.默认构造函数.. int作为arg构造函数..
从另一个构造函数调用构造函数
class MyConstructorDemo extends ConstructorDemo { MyConstructorDemo() { this("calling another constructor"); } MyConstructorDemo(String arg) { System.out.print("This is passed String by another constructor :"+arg); } }
您也可以使用super()
call 调用父构造函数
很简单
public class SomeClass{ private int number; private String someString; public SomeClass(){ number = 0; someString = new String(); } public SomeClass(int number){ this(); //set the class to 0 this.setNumber(number); } public SomeClass(int number, String someString){ this(number); //call public SomeClass( int number ) this.setString(someString); } public void setNumber(int number){ this.number = number; } public void setString(String someString){ this.someString = someString; } //.... add some accessors }
现在这里有一些额外的小功劳:
public SomeOtherClass extends SomeClass { public SomeOtherClass(int number, String someString){ super(number, someString); //calls public SomeClass(int number, String someString) } //.... Some other code. }
希望这可以帮助。
是的,可以使用一个来自另一个构造函数 this()
class Example{ private int a = 1; Example(){ this(5); //here another constructor called based on constructor argument System.out.println("number a is "+a); } Example(int b){ System.out.println("number b is "+b); }
关键字this可用于从构造函数调用构造函数,在为类编写多个构造函数时,有时您希望从另一个构造函数调用一个构造函数以避免重复代码.
Bellow是一个链接,我解释了有关构造函数和getters()和setters()的其他主题,我使用了一个带有两个构造函数的类.我希望解释和例子可以帮到你.
Setter方法或构造函数
有一些设计模式可以满足复杂结构的需求 - 如果不能简洁地完成,则可以创建工厂方法或工厂类.
使用最新的java和lambdas的添加,很容易创建一个构造函数,它可以接受你想要的任何初始化代码.
class LambdaInitedClass { public LamdaInitedClass(Consumerinit) { init.accept(this); } }
叫它......
new LambdaInitedClass(l -> { // init l any way you want });