Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用许多可选数据成员初始化类的Java最佳实践是什么?_Java_Initialization - Fatal编程技术网

用许多可选数据成员初始化类的Java最佳实践是什么?

用许多可选数据成员初始化类的Java最佳实践是什么?,java,initialization,Java,Initialization,我正在将一个项目从C#迁移到Java 我有很多类,它们有很多属性,用户可以设置它们的任何子集 因此,为了初始化类,我提供了一个空构造函数,用户可以使用C#初始化列表初始化任何属性,如下所示: var a = new MyClass() { Prop1 = "something", Prop2 = 8, Prop15 = new Point(2,3) }; 在Java中,这种情况的最佳实践是什么 我看到了以下语法: MyClass a = new MyClass(){

我正在将一个项目从C#迁移到Java

我有很多类,它们有很多属性,用户可以设置它们的任何子集

因此,为了初始化类,我提供了一个空构造函数,用户可以使用C#初始化列表初始化任何属性,如下所示:

var a = new MyClass() { Prop1 = "something", Prop2 = 8, Prop15 = new Point(2,3) };
在Java中,这种情况的最佳实践是什么

我看到了以下语法:

    MyClass a = new MyClass(){
            {
                setProp1("Something");
                setProp2(8);
                setProp15(new Point(2,3));
            }
    };
但是,我知道这不仅仅是一个语法糖,它实际上创建了一个匿名类,并将所有方法放置在新类的初始化块中

因此,我不确定这是否是初始化此类的推荐方法


对于这种情况有什么建议?

您必须为类创建
POJO
,然后使用setter方法初始化它的字段

class MyClass{

  Prop1 = null;
  Prop2 = null;

// getter and setter method

}

您必须为类创建
POJO
,然后使用它的setter方法初始化它的字段

class MyClass{

  Prop1 = null;
  Prop2 = null;

// getter and setter method

}

拥有一个匿名子类的对象通常不是那么糟糕。只有在使用诸如if(object.getClass()==MyClass.class)之类的构造时才会出现问题,但在编写正确的面向对象代码时,这些构造应该不是必需的。最好使用
if(MyClass的对象实例)
,这对于MyClass的子类也是如此,或者最好将任何特定于类的代码放入类本身

初始化具有多个属性的对象的另一种方法是使用模式

创建嵌套在
MyClass
中的公共类,其目的是创建MyClass的实例。因为它嵌套在
MyClass
中,所以它可以访问它正在初始化的实例的所有私有字段。使用这样的构建器可能如下所示:

MyClass a = new MyClass.Builder().setProp1("Something")
                                 .setProp2(8)
                                 .setProp15(new Point(2,3))
                                 .build();
VehicleDef def;
def.wheels = 4;
def.color = Color.RED;
def.brand = Brands.HONDA;
def.type = VehicleTypes.CAR;
def.cylinderVolume = 400;

Vehicle vehicle = new Vehicle(def);

本例使用了一个带有:All setter返回
This的生成器,它允许您在方法调用之间使用一个简单的
链接方法调用。

拥有一个匿名子类的对象通常不是那么糟糕。只有在使用诸如if(object.getClass()==MyClass.class)
之类的构造时才会出现问题,但在编写正确的面向对象代码时,这些构造应该不是必需的。最好使用
if(MyClass的对象实例)
,这对于MyClass的子类也是如此,或者最好将任何特定于类的代码放入类本身

初始化具有多个属性的对象的另一种方法是使用模式

创建嵌套在
MyClass
中的公共类,其目的是创建MyClass的实例。因为它嵌套在
MyClass
中,所以它可以访问它正在初始化的实例的所有私有字段。使用这样的构建器可能如下所示:

MyClass a = new MyClass.Builder().setProp1("Something")
                                 .setProp2(8)
                                 .setProp15(new Point(2,3))
                                 .build();
VehicleDef def;
def.wheels = 4;
def.color = Color.RED;
def.brand = Brands.HONDA;
def.type = VehicleTypes.CAR;
def.cylinderVolume = 400;

Vehicle vehicle = new Vehicle(def);

本例使用了一个带有:All setter返回
This的生成器,它允许您在方法调用之间使用一个简单的
链接方法调用。

我喜欢使用定义类

public class VehicleDef
{
     int wheels;
     Color color;
     Brand brand;
     Type type;
     int cylinderVolume;
     ....
}
现在,您可以创建一个将此VehicleDef类作为参数的构造函数:

public class Vehicle
{
    // all props here:

    public Vehicle (VehicleDef def)
    {
        // set properties and do stuff
    }
}
现在,您可以这样使用它:

MyClass a = new MyClass.Builder().setProp1("Something")
                                 .setProp2(8)
                                 .setProp15(new Point(2,3))
                                 .build();
VehicleDef def;
def.wheels = 4;
def.color = Color.RED;
def.brand = Brands.HONDA;
def.type = VehicleTypes.CAR;
def.cylinderVolume = 400;

Vehicle vehicle = new Vehicle(def);

我喜欢使用定义类

public class VehicleDef
{
     int wheels;
     Color color;
     Brand brand;
     Type type;
     int cylinderVolume;
     ....
}
现在,您可以创建一个将此VehicleDef类作为参数的构造函数:

public class Vehicle
{
    // all props here:

    public Vehicle (VehicleDef def)
    {
        // set properties and do stuff
    }
}
现在,您可以这样使用它:

MyClass a = new MyClass.Builder().setProp1("Something")
                                 .setProp2(8)
                                 .setProp15(new Point(2,3))
                                 .build();
VehicleDef def;
def.wheels = 4;
def.color = Color.RED;
def.brand = Brands.HONDA;
def.type = VehicleTypes.CAR;
def.cylinderVolume = 400;

Vehicle vehicle = new Vehicle(def);

没有双括号初始化:

MyClass a = new MyClass();
a.setProp1("Something");
a.setProp2(8);
a.setProp15(new Point(2,3));
如果(可变)属性的数量很大,那么这就是方法

当某些属性是不可变的(final)时,需要添加特定的构造函数。 可以在构造时向pass属性添加任意数量的其他构造函数(如果可能,还可以添加不带参数的默认构造函数):


没有双括号初始化:

MyClass a = new MyClass();
a.setProp1("Something");
a.setProp2(8);
a.setProp15(new Point(2,3));
如果(可变)属性的数量很大,那么这就是方法

当某些属性是不可变的(final)时,需要添加特定的构造函数。 可以在构造时向pass属性添加任意数量的其他构造函数(如果可能,还可以添加不带参数的默认构造函数):


还有其他方法,但尽管冗长,但我觉得这是最干净的方法。创建
POJO
总是更好的方法,而不是将参数传递给类构造函数,这种方法的缺点是,用户需要编写许多代码行来初始化新实例。如果新实例仅作为某个方法的参数使用,则用户必须首先创建实例,然后对其进行初始化,然后才调用该方法,但是,尽管冗长,我觉得这是最干净的方法。创建
POJO
而不是将参数传递给类构造函数总是更好的方法,以防将来参数发生更改,这将对您有所帮助。这种方法的缺点是,用户只需编写许多代码行来初始化新实例。如果新实例只需要作为某个方法的参数,那么用户必须首先创建实例,然后初始化它,然后调用该方法。这是一种很好的方法。您认为创建这样的生成器比将MyClass中所有setter方法的返回类型更改为MyClass并使类本身成为生成器有什么好处吗?这样就不需要在最后调用.Builder,然后调用.build。显式构建允许验证输入的组合,并执行只有在所有输入已知后才能进行的类初始化。很多商业API都使用这种模式,包括GoogleGuava、AmazonAWS和ProtocolBuffers。这是一种很好的方法。您认为创建这样的生成器比将MyClass中所有setter方法的返回类型更改为MyClass并使类本身成为生成器有什么好处吗?这样就不需要在最后调用.Builder,然后调用.build。显式构建允许验证输入的组合,并执行c