我遇到了一些具有以下结构的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);

其他回答

直接的答案是否定的。

这些答案相当陈旧,主要讨论了即使java没有直接的默认方法参数,我们也可以选择哪些选项。

我们可以用java中的函数式编程轻松地处理这个场景。

我们可以使用java函数式编程的方法currying,我认为它可以最好地用于需要使用默认参数的场景。

在以下情况下,我们可能需要一个默认参数。。。例子:创建一个对两个不同对象有效的方法,并返回计算结果

int mutiply(int a,int b){

      return a*b;

  }

如果我们想有一个乘2的方法,我们必须重写如下方法

int mutiply(int a){

      mutiply(a, 2); // as can not write mutiply(int a,b=2)

  }

上面,2是b的默认值,但它是固定的。如果我们想乘以3,现在我们不能再重载了,而且有多个这样的方法确实很奇怪。

这是我们可以使用方法currying技术的时候。

Currying方法是将多参数函数转换为多个函数的方法,每个函数都接受一个参数。

创建Curried方法的步骤

编写一个接受单个参数并返回另一个参数的函数函数,如下所示。函数<Integer,函数<Integer>>multiply=a->{返回b->a*b;};让我们简化并理解上述方法。

Above方法只接受一个整数Argument,并返回另一个函数,其中一个参数a作为默认值,b作为变量。如果您感到困惑,并开始思考该方法如何使用调用者函数中的变量,而不知道闭包…

“闭包是指在其词汇上下文中引用自由变量的函数。”在这里,在本例中,闭包是对变量multiply进行操作时返回的函数,它有一个自由变量a,它具有调用函数的词法上下文。

返回乘法方法或修复其中一个参数的默认值。//乘法在第一步中定义multiplyByTwo=多重应用(2)multiplyByThree=multiply.apply(3);multiplyByFour=多重应用(4);;等等…将第二个变量传递给返回的函数以获得结果。multiplyByTwo.apply(2)//后果multiplyByTwo.apply(3)//结果6multiplyByThree.应用(2)//结果6multiplyByThree.应用(3)//结果9multiplyByFour.应用(2)//结果8multiplyByFour.应用(3)//结果124

你可以在这里找到我的原始帖子。。。https://www.linkedin.com/pulse/can-we-have-default-method-parameter-java-rajat-singh/?trackingId=yW84I1fzT6WGStrNPAWn4w%3D%3D

有六个或更好的问题,例如,最终,你会发现静态工厂模式。。。请参见加密API。排序很难解释,但可以这样想:如果您有构造函数,默认值或其他值,那么传播状态超出大括号的唯一方法是使用Boolean isValid;(以及null作为默认值v失败的构造函数)或抛出一个异常,当从字段用户处获取该异常时,该异常永远不会提供信息。

代码正确,该死,我写了一千行构造函数,做了我需要的。我发现在对象构造中使用isValid——换句话说,两行构造函数——但出于某种原因,我正在迁移到静态工厂模式。我只是觉得如果在方法调用中仍然存在sync()问题,那么可以做很多事情,但默认值可以更好地“替换”(更安全)

我认为我们需要做的是解决空值作为默认值相对于字符串一=新字符串(“”)的问题;作为成员变量,然后在将字符串分配给构造函数之前检查null。

在Java中完成了大量原始的、同温层的计算机科学。

C++等等都有供应商库,是的。由于Java是一个庞大的工具箱,所以它可以在大型服务器上超越它们。研究静态初始化程序块,和我们呆在一起。

如果您真的想要,可以使用null手动检查:

public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    if(param3 == null) {
        param3 = false;
    }
}

然而,我强烈建议使用其他东西,比如重载或静态工厂。也许你可以逃避这一点,但这可能会导致意想不到的行为。例如,代码中可能有错误,因此布尔值永远不会得到值。在这种情况下,您不会得到NullPointerException。相反,它看起来像是被设置为false,调试时可能会非常混乱。

它在java中不受支持,例如Kotlin在其他语言中也不受支持。

不幸的是,是的。

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

可以用Java 1.5写成:

void MyParameterizedFunction(String param1, int param2, Boolean... params) {
    assert params.length <= 1;
    bool param3 = params.length > 0 ? params[0].booleanValue() : false;
}

但是否应该取决于您对编译器生成

new Boolean[]{}

每次通话。

对于多个默认参数:

void MyParameterizedFunction(String param1, int param2, bool param3=false, int param4=42) {}

可以用Java 1.5写成:

void MyParameterizedFunction(String param1, int param2, Object... p) {
    int l = p.length;
    assert l <= 2;
    assert l < 1 || Boolean.class.isInstance(p[0]);
    assert l < 2 || Integer.class.isInstance(p[1]);
    bool param3 = l > 0 && p[0] != null ? ((Boolean)p[0]).booleanValue() : false;
    int param4 = l > 1 && p[1] != null ? ((Integer)p[1]).intValue() : 42;
}

这与C++语法相匹配,后者只允许在参数列表的末尾使用默认参数。

除了语法之外,还有一个不同之处,即它对传递的默认参数进行了运行时类型检查,而C++在编译过程中对它们进行了类型检查。