例如:
public class App {
private Car car = new Car();
public static void main(String[] args) {
// TO DO
}
}
如果不好,有什么解决方案?你会如何重写这段代码?
答案 0 :(得分:1)
在我看来,一切都取决于您正在使用的应用程序的设计。对于提供的示例,我认为这是可以接受的。但对于其他更确定的数据类型,我更喜欢构造函数初始化。主要是因为构造函数重载是可能的。
答案 1 :(得分:1)
我一直被告知你在上面声明并在里面初始化。初始化构造函数内部的东西更有效,因为如果需要在构造时使用传入的参数更改它,则在初始化时初始化和分配。
例如:
public class TestClass{
//Declared but uninitialized
Object obj;
//Makes no difference but easier to read
public TestClass(){
this.obj = new Object();
}
//In this constructor however the object being passed in is what is initializing obj
//-so if you were to initialize it above and then change it down here you are writing
//-to the mem twice and it is less efficient.
public TestClass(Object arg){
this.obj = (Object)arg;
}
}
对此的警告是,这些天的记忆真的很便宜。这样做的唯一真正目的(除了不想看起来像一个新手)是让其他人可以管理。
答案 2 :(得分:1)
如果程序“始终”需要对象的实例并且创建实例的成本不是太大(时间,资源),则可能会在声明中初始化对象。然后是的,可能需要这种“渴望初始化”。
然而,这种设计确实违背了OO设计,使类松散耦合并使单元测试更加困难。
在示例中:
public class App {
private Car car = new Car();
}
你在说:
理想情况下,您只想在实际需要时创建对象。或者在构造函数(默认或重载)中提供一些灵活性。
public class App {
private Car car;
App() {
}
// overloaded constructor
App(Car car) {
this.car = car;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return car;
}
public static void main(String[] args) {
// default constructor, lightweight, no car initialization happening;
App ap1 = new App();
// Ok, now I want a car, and it should be red.
Car redCar = new Car("red");
ap1.setCar(redCar);
// Using overloaded constructor, now I can control aspects of "car"
Car blueCar = new Car("blue");
App ap2 = new App(blueCar);
}
}
答案 3 :(得分:0)
如果您希望代码更容易测试,那么这是一种不好的做法。原因是,无论您是否愿意,创建App
也会创建Car
。现在,如果Car
具有连接到数据库的代码,则oops,现在当您测试App
时,您需要有可用的数据库,否则您的测试将失败。
解决方案是依赖注入,即控制反转。你会这样写:
public class App {
private Car car;
public App(Car car) {
this.car = car;
}
public static void main(String[] args) {
// TO DO
}
}
现在创建App
并不一定会创建Car
并且它们的耦合程度更低。
现在,我在这里非常迂腐。我可能一直在我的代码中使用你的例子。我只是指出了一个缺点。这并不总是坏事,并不总是好的。
答案 4 :(得分:0)
私人汽车=新车();
这完全可以恕我直言。 不这样做的几个原因:
Car.<init>
需要仅在App.init
App
有许多字段,其他字段需要在App.<init>
中初始化,并且为了保持一致性,您希望将它们保持在一起。在任何情况下,请勿执行以下操作:
私人汽车= null;
因为每个java开发人员都知道实例字段被初始化为null
。
答案 5 :(得分:0)
除了tieTYT写的内容之外,可能值得考虑的是,如果你在构造函数中实例化所有成员,它会使它更具可读性。您可以通过阅读构造函数来学习有关该类型的新对象的所有知识。
答案 6 :(得分:0)
请注意:
之间的含义有所不同public class App {
private Car car = new Car();
public static void main(String[] args) {
// TO DO
}
}
和
public class App {
private Car car;
public App(){
car = new Car();
}
}
例如,如果新的Car()在第一个失败,那么你肯定会有一个愉快的时间进行调试。如果需要,第二个更具可读性和可调试性。如果你认为字段是类的蓝图的一部分,那么在它们的声明中初始化它们是没有意义的。 既然你有这里的主要内容,这可能是你的切入点,但对于其他类,如果你把它们看作是对象的蓝图,那么构造函数的概念很有意义:
public class App{
private Car car;
public Car getCar(){
return car;
}
public void setCar(Car car){
this.car = car;
}
public App(Car car){
this.car = car;
}
}
我想,这是oop类最常见的结构。
答案 7 :(得分:0)
执行此代码的最佳方法是在main方法中创建一个类型为App的Object,它将调用Car类的构造函数。所以代码就是这样。
公共类App {
private Car car;
public static void main(String[] args)
{
App app=new App(); //
app.car. //Followed by the method or the member variable that you would like to
//access
}
}
答案 8 :(得分:0)
使用Init()方法进行所有初始化。
公共类App {
private Car car;
public App() {
this.car = null;
}
public void Init() {
this.car = new Car();
}
public void Shutdown() {
this.car = null;
}
public static void main(String[] args) {
App app = new App();
app.Init();
app.Shutdown();
app = null;
}
}