有时我推理一些基本的东西。例如,这一次,我可以使用以下内容来避免java中的构造函数,
请考虑我明白默认构造函数将由jvm提供
class TestConstructor {
private String cusName;
private String dbConnectionURL;
private Customer cus;
// avoiding constructor through this init method
public void init(String cusName, String dbConnectionURL, Customer cus) {
this.cus = cus;
this.dbConnectionURL = dbConnectionURL;
this.cusName = cusName;
}
public boolean connectToDatabase(some parameter)
// some code may be to connect to database
return connectionSuccessful;
}
public boolean isCustomerSatisfied() {
// some code to perform some operation
}
// some more methods to do more stuff
然后我可以初始化类并按以下方式使用该类?
TestConstructor tc = new TestConstructor();
tc.init("John", "db connection string", new Customer(x, y, z));
tc.connectToDatabase(required args go here);
tc.isCustomerSatisfied(required args go here);
我能想到的唯一问题是你可以在同一个构造函数上调用init并更改对象的值..这是一个安全问题,也许是最主要的问题。
但还有别的吗?
请原谅我这是一个糟糕的问题。刚刚来到我的脑海
实际上我一直在为面试做准备,并且正在思考如果我被问到这样一个问题 - "构造函数可以通过这种方式实现,那么为什么需要构造函数?"以下我开始考虑它
我很惊讶大多数人都坚持使用静电' ..代码只是给出一个想法的样本。真正的问题是你可以避免构造函数,但你可以逃脱它吗?有什么缺点
答案 0 :(得分:2)
您无法在静态方法(您的this
方法)中引用init
,因为静态方法无法访问该类的实例(除非您将其传递给实例作为参数)。
如果要使用默认构造函数创建实例并使用init
方法初始化其成员,请删除static
关键字。
除了静态方法的问题,您当然可以使用非构造方法来初始化实例。但是,你在这里获得了什么?对init方法的调用与带参数的构造函数相同。主要区别在于,正如您所提到的,您可以多次调用此init方法。
答案 1 :(得分:1)
您似乎正在尝试创建“工厂方法”。
以下版本不正确(它不会编译!)因为static
方法无法使用this
。此外,您没有返回实例。
public static void init(String cusName, String dbConnectionURL, Customer cus) {
this.cus = cus;
this.dbConnectionURL = dbConnectionURL;
this.cusName = cusName;
}
但如果你按如下方式编写,它应该可以工作:
public static TestConstructor init(String cusName, String dbConnectionURL,
Customer cus) {
TestConstructor res = new TestConstructor();
res.cus = cus;
res.dbConnectionURL = dbConnectionURL;
res.cusName = cusName;
return res;
}
使该方法“正常”的另一种方法是将字段更改为static
。但是那时只有一组变量......由使用该类的所有线程共享,等等。另一方面,可能就是你想要实现的目标。
第三种可能性是你打算在构造之后使用init
方法初始化对象; e.g。
public TestConstructor() { }
public void init(String cusName, String dbConnectionURL, Customer cus) {
this.cus = cus;
this.dbConnectionURL = dbConnectionURL;
this.cusName = cusName;
}
然后
TestConstructor tc = new TestConstructor();
tc.init("fred", someURL, someCustomer);
有效......但我认为这样做并没有什么大的优势。缺点是你的TestConstructor
对象是在未初始化/部分初始化的状态下构建的......从“抽象”的角度来看这是不好的。
真正的问题是你可以避免使用构造函数,但是你可以逃脱它吗?有什么缺点
是的,你可以。
一个缺点是,如果你有final
个实例变量,那么只能在构造函数中初始化(或者在构造函数代码之前运行的初始化程序块)。依赖于参数的工厂方法和final
实例变量不会混合。这同样适用于在新构造的实例上调用的init
方法。
但也存在好处。例如,工厂方法可以是工厂对象的实例方法,并且允许您解决使用new
的一些问题。 (例如,您只能new
一个特定的类。)
答案 2 :(得分:0)
有趣的是,这就是JVM在幕后所做的事情 - 甚至还有一个名为''的方法对应于构造函数。但是,构造函数并不只是帮助设置参数,它们就在那里,以便系统可以保证已经设置了一些参数(或它们的有效组合)。