我正在将项目从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));
}
};
但是,我知道这不仅仅是一个语法糖,它实际上创建了一个匿名类,并将所有方法放在新类的初始化块中。
所以我不确定这是初始化这样一个类的推荐方法。
这种情况的建议是什么?
答案 0 :(得分:2)
您必须为您的班级创建POJO
,然后使用它的setter方法初始化它。
class MyClass{
Prop1 = null;
Prop2 = null;
// getter and setter method
}
答案 1 :(得分:2)
拥有匿名子类的对象通常并不坏。当你使用if (object.getClass() == MyClass.class)
这样的结构时,它只会成为一个问题,但是当你编写适当的面向对象的代码时,这些并不是必需的。更好地使用if (object instanceof MyClass)
,对于MyClass的子类也是如此,或者更好地将任何特定于类的代码放入类本身。
初始化具有许多属性的对象的另一种方法是使用Builder模式。
创建一个嵌套在MyClass
内的公共类,其目的是创建一个MyClass实例。因为它嵌套在MyClass
内,所以它可以访问它正在初始化的实例的所有私有字段。使用这样的构建器可能如下所示:
MyClass a = new MyClass.Builder().setProp1("Something")
.setProp2(8)
.setProp15(new Point(2,3))
.build();
此示例使用带有fluent interface的构建器:所有setter返回this
,允许您在方法调用之间使用简单的.
进行链接。
答案 2 :(得分:2)
我喜欢使用定义类。
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
}
}
现在,您可以像这样使用它:
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);
答案 3 :(得分:0)
没有双括号初始化:
MyClass a = new MyClass();
a.setProp1("Something");
a.setProp2(8);
a.setProp15(new Point(2,3));
如果(可变)属性的数量很大,这是可行的方法。
当某些属性是不可变的(最终)时,添加特定的构造函数是必要的。 可以添加任意数量的附加构造函数以在构造时传递属性(如果可能,还添加一个没有args的默认构造函数):
public class MyClass {
// default constructor
public MyClass() {
}
// convenience constructor
public MyClass(String s, int i, Point p) {
setProp1(s);
setProp2(i);
setProp15(p);
}
}