【问题标题】:(Java) Can I create an object and use a setter on the same line?(Java) 我可以创建一个对象并在同一行上使用 setter 吗?
【发布时间】:2018-01-11 12:25:34
【问题描述】:

是否可以在 JAVA 中创建一个对象,然后在同一行立即使用 setter?

像这样:Class classname = new Class().setSomething("String");

我怎样才能正确地做到这一点,eclipse总是说:

类型不匹配:无法从 void 转换为类型 Class

【问题讨论】:

  • 我认为你想要的是所谓的建造者模式。在你的情况下你不能这样做,因为 setter 没有返回值
  • 只有在setter返回Class对象时才有可能,但不推荐
  • new Class().setSomething("String"); 非常好,但是除非 setSomething 方法返回 Class 类型的对象,否则不会将该行分配给 Class classname
  • 您可能需要考虑创建一个接受参数的构造函数。

标签: java eclipse object variables setter


【解决方案1】:

您得到的错误只是因为setSomething() 的返回值是void。例如。方法如下所示;

public void setSomething(String something){
    this.something = something;
}

因为void 不能分配给任何你不能内联创建对象并调用它的方法的东西。但是将签名更改为这样的东西仍然是可能的:

class MyClass{
    private String something;

    public MyClass setSomething(String something){
        this.something = something;
        return this; // returning this
    }
}

return this 的这种用法称为method-chaining,主要出现在构建器模式中。

虽然上述方法可能有效,但您可能希望在创建MyClass 的实例时始终将something 设置为一个值。为此,您必须添加一个自定义构造函数,该构造函数接受something 的初始值。例如:

class MyClass{

    private final String something;

    public MyClass(String something){
        this.something = something;
    }
}

然后可以像下面这样使用:

MyClass myclass = new MyClass("Something");

后者优于前者。因为这样对象是使用值集创建的,并且不能处于无效状态。 (例如,当没有设置something 时,可能会导致讨厌的NullPointerExceptions)。

注意:您可能已经看到我在声明变量something 时使用了关键字final。如果您希望稍后能够将 something 更改为不同的值,则可以省略此操作,但是当您将其保留原样时,您创建了一个不可变的 MyClass 实例,该实例通常优于可变实例。

【讨论】:

    【解决方案2】:

    您可以使用 @Jens 所说的 Builder Pattern 来做类似的事情。

    public class Car {
    
       private String brand;
    
       public Car(String brand) {
          this.brand = brand;
       }
    
       public static class Builder {
    
          private String brand;
    
          public static Builder withBrand(String newBrand) {
             Builder builder = new Builder();
             builder.brand = newBrand;        
             return builder;
          }
    
          public static Car build() {
             return new Car(this.brand);
          }
       }
    }
    

    所以你可以这样叫新车:

    Car evoque = new Car.Builder().withBrand("Range Rover").build();
    

    当您有许多属性要设置并且不想要大量的构造函数时,构建器模式非常有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多