我可以避免构造函数

时间:2014-07-30 02:59:06

标签: java oop

有时我推理一些基本的东西。例如,这一次,我可以使用以下内容来避免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并更改对象的值..这是一个安全问题,也许是最主要的问题。

但还有别的吗?

请原谅我这是一个糟糕的问题。刚刚来到我的脑海

实际上我一直在为面试做准备,并且正在思考如果我被问到这样一个问题 - "构造函数可以通过这种方式实现,那么为什么需要构造函数?"以下我开始考虑它

我很惊讶大多数人都坚持使用静电' ..代码只是给出一个想法的样本。真正的问题是你可以避免构造函数,但你可以逃脱它吗?有什么缺点

3 个答案:

答案 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在幕后所做的事情 - 甚至还有一个名为''的方法对应于构造函数。但是,构造函数并不只是帮助设置参数,它们就在那里,以便系统可以保证已经设置了一些参数(或它们的有效组合)。