对象方法调用可以和对象实例化同时进行吗?
Can object method call be done simultaneously with object instantiation?
我正在尝试使用 java class BitSet
作为自定义 class 的字段。我希望 class 使用所有位都设置的默认 BitSet。
import java.util.BitSet;
public class MyClass {
private BitSet mask;
public MyClass() {
this(new BitSet(4));
// want to set all bits first
// something like
// this( new BitSet(4).set(0,3) );
}
public MyClass(BitSet mask) {
this.mask = mask;
}
}
默认情况下 BitSet
构造函数取消设置所有位。所以在我将它作为匿名对象发送之前,我想调用 set(int, int)
方法来设置所有位。我知道我可以简单地将字段 mask
初始化为新的 BitSet
,然后从那里调用 set(int, int)
方法。
但是,一般来说,我想知道是否可以在对象实例化时访问实例方法?
否;这必须作为一个单独的调用来完成,它将在对象的构造完成后执行。在你的情况下,在一行中完成它的唯一方法是如果方法的 return 类型是 BitSet
并且方法已经 returned 调用它的实例,在这种情况下你本来可以的
this(new BitSet(4).set(0, 1)); // Doesn't actually work
很遗憾,set()
是 void
,所以您不能这样做。
BitSet 没有流畅的界面,因此 new BitSet(4).set(0,3)
之类的东西不适用于 BitSet。只有静态 BitSet.valueOf() 方法,但使用起来有些笨拙。但是,如果你想要一个静态配置,你可以只用所需的值实例化一个 BitSet,使用 BitSet.toLongArray(),打印数组值并用它实例化你的 BitSet。在您的特定示例中,默认构造函数可能是:
public MyClass() {
this(BitSet.valueOf(new long[]{7}));
}
至于问题的一般部分:只有当您有 "setter" 当前对象 returns 时,它才会起作用,这将允许您链接调用。所以对于你自己的 类 你可以这样做:
public class A {
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public A withNum(int num) {
setNum(num);
return this;
}
}
如果你在像 BitSet 这样的构造函数中使用它,你可以做到 this(new A().withNum(4));
Fluent 接口非常流行(例如 AWS SDK 到处都有),只是 JDK 对象通常没有。
为什么不编写一个允许 BitSet
初始化的单独构造函数?使用 Java 8,这看起来像这样:
public class MyClass {
private BitSet mask;
public MyClass() {
this(new BitSet(4),(m)->m.set(0,3));
}
public MyClass(BitSet mask,Consumer<BitSet> initializer) {
initializer.accept(mask);
this.mask = mask;
}
}
您甚至可以通过引入带有类型参数的静态方法来使其更加通用:
public static <T> T initialize(T t,Consumer<T> initializer) {
initializer.accept(t);
return t;
}
在那种情况下,较早的 MyClass
将如下所示:
public class MyClass {
private BitSet mask;
public MyClass() {
this(initialize(new BitSet(4),(m)->m.set(0,3)));
}
public MyClass(BitSet mask) {
this.mask = mask;
}
}
更新
还有一种方法,无需引入新方法或构造函数:
public class MyClass {
private BitSet mask;
public MyClass() {
this(new BitSet(4) {{ set(0,3); }});
}
public MyClass(BitSet mask) {
this.mask = mask;
}
}
一个anonymous class is being instantiated by extending BitSet
and adding an instance initialization block, hence the double curly braces.
我正在尝试使用 java class BitSet
作为自定义 class 的字段。我希望 class 使用所有位都设置的默认 BitSet。
import java.util.BitSet;
public class MyClass {
private BitSet mask;
public MyClass() {
this(new BitSet(4));
// want to set all bits first
// something like
// this( new BitSet(4).set(0,3) );
}
public MyClass(BitSet mask) {
this.mask = mask;
}
}
默认情况下 BitSet
构造函数取消设置所有位。所以在我将它作为匿名对象发送之前,我想调用 set(int, int)
方法来设置所有位。我知道我可以简单地将字段 mask
初始化为新的 BitSet
,然后从那里调用 set(int, int)
方法。
但是,一般来说,我想知道是否可以在对象实例化时访问实例方法?
否;这必须作为一个单独的调用来完成,它将在对象的构造完成后执行。在你的情况下,在一行中完成它的唯一方法是如果方法的 return 类型是 BitSet
并且方法已经 returned 调用它的实例,在这种情况下你本来可以的
this(new BitSet(4).set(0, 1)); // Doesn't actually work
很遗憾,set()
是 void
,所以您不能这样做。
BitSet 没有流畅的界面,因此 new BitSet(4).set(0,3)
之类的东西不适用于 BitSet。只有静态 BitSet.valueOf() 方法,但使用起来有些笨拙。但是,如果你想要一个静态配置,你可以只用所需的值实例化一个 BitSet,使用 BitSet.toLongArray(),打印数组值并用它实例化你的 BitSet。在您的特定示例中,默认构造函数可能是:
public MyClass() {
this(BitSet.valueOf(new long[]{7}));
}
至于问题的一般部分:只有当您有 "setter" 当前对象 returns 时,它才会起作用,这将允许您链接调用。所以对于你自己的 类 你可以这样做:
public class A {
private int num;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public A withNum(int num) {
setNum(num);
return this;
}
}
如果你在像 BitSet 这样的构造函数中使用它,你可以做到 this(new A().withNum(4));
Fluent 接口非常流行(例如 AWS SDK 到处都有),只是 JDK 对象通常没有。
为什么不编写一个允许 BitSet
初始化的单独构造函数?使用 Java 8,这看起来像这样:
public class MyClass {
private BitSet mask;
public MyClass() {
this(new BitSet(4),(m)->m.set(0,3));
}
public MyClass(BitSet mask,Consumer<BitSet> initializer) {
initializer.accept(mask);
this.mask = mask;
}
}
您甚至可以通过引入带有类型参数的静态方法来使其更加通用:
public static <T> T initialize(T t,Consumer<T> initializer) {
initializer.accept(t);
return t;
}
在那种情况下,较早的 MyClass
将如下所示:
public class MyClass {
private BitSet mask;
public MyClass() {
this(initialize(new BitSet(4),(m)->m.set(0,3)));
}
public MyClass(BitSet mask) {
this.mask = mask;
}
}
更新
还有一种方法,无需引入新方法或构造函数:
public class MyClass {
private BitSet mask;
public MyClass() {
this(new BitSet(4) {{ set(0,3); }});
}
public MyClass(BitSet mask) {
this.mask = mask;
}
}
一个anonymous class is being instantiated by extending BitSet
and adding an instance initialization block, hence the double curly braces.