我遇到了一些具有以下结构的Java代码:

public MyParameterizedFunction(String param1, int param2)
{
    this(param1, param2, false);
}

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    //use all three parameters here
}

我知道,在C++中,我可以为参数指定默认值。例如:

void MyParameterizedFunction(String param1, int param2, bool param3=false);

Java是否支持这种语法?这两步语法是可取的,有什么原因吗?


当前回答

您可以使用Java方法调用生成器自动生成具有默认值的生成器。

只需将@GenerateMethodInvocationBuilder添加到类或接口,并将@Default添加到需要默认值的方法中的参数。编译时将使用您在注释中指定的默认值生成生成器。

@GenerateMethodInvocationBuilder
public class CarService {
 public CarService() {
 }

 public String getCarsByFilter(//
   @Default("Color.BLUE") Color color, //
   @Default("new ProductionYear(2001)") ProductionYear productionYear,//
   @Default("Tomas") String owner//
 ) {
  return "Filtering... " + color + productionYear + owner;
 }
}

然后可以调用这些方法。

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .invoke(instance);

或者将任何默认值设置为其他值。

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .withColor(Color.YELLOW)//
  .invoke(instance);

其他回答

您可以使用以下选项-

public void mop(Integer x) {
  // Define default values
        x = x == null ? 200 : x;
}

类似的方法https://stackoverflow.com/a/13864910/2323964在Java8中工作的是使用带有默认getter的接口。这将使空白更加冗长,但可以模拟,并且非常适合在有大量实例需要注意参数的情况下使用。

public class Foo() {
    public interface Parameters {
        String getRequired();
        default int getOptionalInt(){ return 23; }
        default String getOptionalString(){ return "Skidoo"; }
    }

    public Foo(Parameters parameters){
        //...
    }

    public static void baz() {
        final Foo foo = new Foo(new Person() {
            @Override public String getRequired(){ return "blahblahblah"; }
            @Override public int getOptionalInt(){ return 43; }
        });
    }
}

我就是这样做的。。。这可能不如对定义的参数使用“可选参数”方便,但它可以完成任务:

public void postUserMessage(String s,boolean wipeClean)
{
    if(wipeClean)
    {
        userInformation.setText(s + "\n");
    }
    else
    {
        postUserMessage(s);
    }
}

public void postUserMessage(String s)
{
    userInformation.appendText(s + "\n");
}

注意,我可以只使用字符串调用同一个方法名,也可以使用字符串和布尔值调用它。在这种情况下,将wipeClean设置为true将用提供的字符串替换TextArea中的所有文本。将wipeClean设置为false或将其全部忽略,只需将提供的文本附加到TextArea。

另外请注意,我并没有重复这两个方法中的代码,我只是添加了一个功能,即通过创建一个同名的新方法(仅使用添加的布尔值)来重置TextArea。

实际上,我认为这比Java为我们的参数提供“可选参数”要简单一些,因为我们需要为默认值等进行编码。在本例中,我不需要担心这些问题。是的,我在课堂上增加了另一种方法,但从长远来看,我个人认为这更容易阅读。

没有,但最简单的实现方法是:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    param3 = param3 == null ? false : param3;
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

或代替三元运算符,可以使用以下条件:

public myParameterizedFunction(String param1, int param2, Boolean param3) {

    if (param3 == null) {
        param3 = false;
    }
}

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

不,但你可以很容易地模仿它们。C++中的内容是:

public: void myFunction(int a, int b=5, string c="test") { ... }

在Java中,它将是一个重载函数:

public void myFunction(int a, int b, string c) { ... }

public void myFunction(int a, int b) {
    myFunction(a, b, "test");
}

public void myFunction(int a) {
    myFunction(a, 5);
}

前面提到过,默认参数导致函数重载中出现不明确的情况。这根本不是真的,我们可以在C++的例子中看到:是的,也许它会产生模棱两可的情况,但这些问题可以很容易地处理。它根本不是用Java开发的,可能是因为创建者想要一种像C++那样简单得多的语言——如果他们有权利的话,这是另一个问题。但我们大多数人并不认为他使用Java,因为它很简单。