对象方法调用是否可以与对象实例同时完成?

时间:2016-04-23 03:35:30

标签: java this instantiation

我正在尝试使用java类BitSet作为自定义类的字段。我希望该类使用默认的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)方法。

但是,总的来说,我想知道在对象实例化时是否可以访问实例方法?

3 个答案:

答案 0 :(得分:3)

为什么不编写一个允许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;
  }
}

通过扩展BitSet并添加anonymous class来实例化instance initialization block,因此double curly braces

答案 1 :(得分:2)

BitSet没有流畅的界面,因此像new BitSet(4).set(0,3)这样的东西对BitSets不起作用。只有静态的BitSet.valueOf()方法,但这些方法使用起来有些尴尬。但是,如果您想要静态配置,您只需要实例化具有所需值的BitSet,请使用BitSet.toLongArray(),打印数组值并使用它实例化BitSet。在您的具体示例中,默认构造函数可以是:

public MyClass() {
    this(BitSet.valueOf(new long[]{7}));
}

至于问题的一般部分:只有你有一个&#34; setter&#34;返回当前对象,允许您链接调用。所以对于你自己的课程,你可以这样做:

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对象通常没有它们。

答案 2 :(得分:0)

没有;这必须作为一个单独的调用来完成,该调用将在对象的构造完成后执行。在你的情况下在一行中执行它的唯一方法是,方法的返回类型是BitSet并且方法已经返回了它被调用的实例,在这种情况下你可以完成

this(new BitSet(4).set(0, 1)); // Doesn't actually work

不幸的是,set()void,因此您无法做到这一点。