在C#中存在一种称为Property的成员。这使您可以轻松简单地定义私有字段并提供简单或复杂的getter和setter,同时通过不必定义整个方法来节省空间。 Java没有这样的东西,从我所看到的,普遍的共识是吸收它并为私有变量定义完整的getter和setter方法。
目前,我一直在玩弄以下课程:
public class Property<T> {
private T value = null;
public Property(){}
public Property(T initialValue){
value = initialValue;
}
public T get(){
return value;
}
public void set(T newValue){
value = newValue;
}
}
通过此实现,您可以定义仅需要getter和setter的简单属性:
final Property<String> name = new Property<>("Dog");
或更高级的选项like the one that MSDN provides for C#:
...
public double seconds;
public final Property<Double> Hours = new Property<Double>(){
@Override
public Double get() {
return seconds/3600;
}
@Override
public void set(Double newValue) {
seconds = newValue * 3600;
}
};
...
这个解决方案的优点和缺点是什么?
答案 0 :(得分:2)
专业人士很明显。我会指出一些比C#更好的特性:
与C#的自动属性不同,您可以选择仅覆盖get
或set
方法,而不是两者,例如。
public Property<List<String>> MyList = new Property<List<String>>(){
@Override
public List<String> get() {
if (value == null)
value = new ArrayList<String>();
return value;
}
// set still works
};
但是有缺点:
get
和set
方法的可见性:如果可以访问Property<T>
,则可以获取并设置值。Property
字段final
,则可以访问该字段的任何人都可以将其更改为自己的Property
实施。这可能很有用,但主要是痛苦。get
和set
方法的参数。例如。您不能同时使用Property<MyType>
和set(MyType)
方法set(CompatibleType)
(除非您延长Property
)。Object
。如果您使用原语(例如,使用double
vs Property<Double>
),此装箱/拆箱可能会略微降低性能(在大多数应用中都不会引人注意)。顺便说一下,Scala是一种在JVM上运行的语言,它包含属性作为本机功能,并与Java的属性版本(getter / setter)互操作。您可能想要研究一下,因为基本上其他人已经为您破解了Java语言。 =)
总而言之,我会说你不应该试图让Java拥有属性。在罗马做到入乡随俗。如果你不喜欢罗马人的行为,那就沿着街道(斯卡拉)或全国各地(C#)行走。
答案 1 :(得分:1)
因此,对于名称,完整的语法现在将是:
theObject.name.set("new name");
关键是,你是如何访问该名称对象的?它是公共/受保护然后它可以被覆盖。它是私人的吗?那么你无论如何都不能在课外改变它。
您提出的解决方案只有在您已有权访问该对象时才有效,此时您不需要该解决方案。
答案 2 :(得分:0)
此解决方案的优点(您的匿名内部类)是,如果您不需要在其他任何地方实现此功能,它将使您免于为这种情况编写完整的额外类。
此解决方案的con 以后您可能希望在其他位置实现它,然后您需要重构代码以提取Property&lt; Double&gt;的实现。进入自己的班级以避免重复自己。
我会说,如果你很确定你不会在其他地方需要这个实现(我猜你不会),请继续使用后面的解决方案一个匿名的内部类。这是一个很好的。