0

对于下面的代码段,为什么方法的定义read有一个MyWritable,而其他两个方法writereadFields没有?此外,为什么read要定义为静态?如何理解这个设计?

public class MyWritable implements Writable {
   // Some data     
   private int counter;
   private long timestamp;

   public void write(DataOutput out) throws IOException {
     out.writeInt(counter);
     out.writeLong(timestamp);
   }

   public void readFields(DataInput in) throws IOException {
     counter = in.readInt();
     timestamp = in.readLong();
   }

   public static MyWritable read(DataInput in) throws IOException {
     MyWritable w = new MyWritable();
     w.readFields(in);
     return w;
   }
 }
4

5 回答 5

1

答案很简单。

staticread 方法允许您在实际类上调用该方法并返回一个实例。所以,而不是这样做:

MyWritable writer = new MyWritable();
writer.readFields(input);

你可以这样做:

MyWritable writer = MyWritable.read(input);

并达到同样的效果。是为了方便。

然后,它返回 aMyWritable因为否则你永远不会得到对象!第一个方法可以返回void,因为您已经创建了一个对象实例,但在后者中,它必须返回它为您创建的实例。

于 2013-09-04T19:40:17.773 回答
1

这种设计实现了一个非常简单的工厂方法模式:用户会调用read,而不是调用new MyWritable()后跟readFields().

完成工厂方法模式的实现,制作构造函数private,通过接口返回构造好的对象:

private MyWritable() {} // Disallow external instantiations

// Use the Writable interface rather than MyWritable as the return type
public static Writable read(DataInput in) throws IOException {
    MyWritable w = new MyWritable();
    w.readFields(in);
    return w;
}
于 2013-09-04T19:40:51.610 回答
0

实际上,看起来他们正在尝试创建一个简单的入口点来读取这些项目,而不是“新建”未知的可写内容。所以:MyWritable.read(dataInput);

它在 MyWritable 的内存中创建一个实例(我们称之为 myWritable1)。然后他们调用“myWritable1.readFields”并允许它自己“读取”和“填充”。

MyWritable.read(dataInput) 将返回 myWritable1(在上面创建)。

静态读取方法完全没有必要,甚至可能不是一个好主意。它使它易于使用,但并没有真正节省很多工作。new MyWritable().readFields(dataInput) 也可以。

于 2013-09-04T19:39:55.160 回答
0
  • 它返回 a MyWritable,因此您可以在阅读后对其进行处理,例如查看数据。
  • 它是静态的,因为它是一种工厂/便利方法。
  • 其他人没有,因为如果您调用实例方法,您已经有一个实例。
于 2013-09-04T19:40:18.070 回答
0

在这种情况下,该方法是基于某些数据read(DataInput)创建的工厂方法。MyWritable它有一个返回类型,因为它返回它创建的对象。它是静态的,因为非静态工厂方法没有多大意义(如何在尚未创建的对象上调用方法?)

于 2013-09-04T19:41:01.980 回答