Java 是否支持缺省参数值?

Does Java support default parameter values?

提问人:gnavi 提问时间:6/16/2009 最后编辑:Wolfgnavi 更新时间:2/17/2023 访问量:1969346

问:

我遇到了一些具有以下结构的 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 方法 参数 重载 default-parameters

评论

116赞 Dave Jarvis 5/27/2010
不。但是,生成器模式可以提供帮助。
6赞 Erwin Bolwidt 1/12/2015
@Jatin 通过 Eclipse 的“更改方法签名”重构,您可以添加一个参数,并提供现有调用者将使用的默认值。
2赞 Jatin 1/14/2015
@ErwinBolwidt 谢谢。我正在使用 Android Studio,它还可以选择重构方法并提供默认值。相当有用。
0赞 E A 1/11/2019
使用静态工厂方法!
3赞 Mario Ishac 1/25/2019
@temporary_user_name 是构造函数,而不是方法声明。public MyParameterizedFunction(String param1, int param2)

答:

351赞 Rob H 6/16/2009 #1

可悲的是,没有。

评论

35赞 Trey 6/16/2009
有那么难过吗?这样做会引入潜在的模棱两可的函数签名。
81赞 PhiLho 5/24/2011
@Trey:具有默认参数的语言通常会放弃函数重载,因为它不那么引人注目。所以没有歧义。此外,Scala 在 2.8 中添加了该功能,并以某种方式解决了歧义问题(因为他们出于兼容性原因保留了重载)。
2赞 Antony Booth 11/15/2013
我相信参数默认值是不好的做法,重载是一个更干净的解决方案。您甚至可以隐藏默认构造函数,并使用静态工厂方法返回初始化的实例。这对于 IOC 也很有用,您可以在 IOC 中确定要返回的接口的实现。如果要选择性地分配属性、创建公共属性或重载构造函数,则使用另一种方式执行相同的功能并不会使它变得更好。它只是使语言更加神秘,当这是函数重载的原因之一时,它只是懒惰的编程。
44赞 FlavorScape 12/1/2013
我看不到参数默认值如何防止函数重载。例如,C# 允许重写,也允许默认初始化。似乎是任意选择,而不是限制是原因。
4赞 spyro 10/13/2016
在 C# 中工作多年,没有问题,即使与方法重载相结合。编译器显示有关冲突的警告,仅此而已。只需执行类似 writeToFile(String content, boolea append=false) 的操作即可;
1202赞 Kathy Van Stone 6/16/2009 #2

不,您找到的结构是 Java 处理它的方式(即使用重载而不是默认参数)。

对于构造函数,请参阅 Effective Java: Programming Language Guide 的第 1 项提示(考虑静态工厂方法而不是构造函数)

如果过载变得复杂。对于其他方法,重命名某些事例或使用参数对象会有所帮助。

这是当你有足够的复杂性,很难区分的时候。一个明确的情况是,您必须使用参数的顺序进行区分,而不仅仅是数字和类型。

评论

32赞 12/18/2015
这是在 2009 年,在 2015 年,任何事情都被认为是有害的。现在,强制执行完整且有效的施工合同的类型安全流畅的 Builder 实例是一个更好的解决方案。static
188赞 Lii 1/22/2016
@JarrodRoberson:静态工厂方法的危害并不比 。它们在新代码中一直使用。简单值对象的构建器通常是过度设计的结果。new
6赞 Santosh Gokak 6/16/2009 #3

不。

您可以通过传递具有智能默认值的 Object 来实现相同的行为。但同样,这取决于您手头的情况。

6赞 tomjen 6/16/2009 #4

不。一般来说,Java没有太多(任何)语法糖,因为他们试图创造一种简单的语言。

评论

30赞 Martin 9/18/2011
差一点。苦涩的事实是,团队的日程安排很紧,没有时间进行句法糖。为什么还会和保留没有实现的关键字?——尤其是我非常想念的东西——是无可替代的,他们知道这一点。— 如果你做出了永不实施的明智决定,你就不需要保留关键词。— 后来在 Java 团队中,通过使 Label 基于 Pascal 并像 Pascal 一样强大来作弊。constgotoconstfinalgotobreakcontinuegoto
0赞 mikera 9/2/2013
“简单、面向对象和熟悉”确实是一个设计目标 - 参见 oracle.com/technetwork/java/intro-141325.html
1赞 8/8/2017
tomjen说:“没有。一般来说,Java没有太多(任何)语法糖,因为他们试图创造一种简单的语言。所以你是说从C++中删除很多不必要的功能使Java成为一种简单的语言,那么告诉我为什么Java确实有可变方法?为什么它有 varargs?如果您可以简单地使用对象数组,则不需要它,对吗?因此,可以从语言中删除 varargs,因为它是不必要的。这将使 Java 比现在更简单。我说得对吗?重载也可以删除,因为每个方法都有无限个名称。
767赞 Eli Courtwright 6/16/2009 #5

否,但您可以使用 Builder 模式,如此 Stack Overflow 答案中所述。

如链接答案中所述,Builder Pattern 允许您编写类似

Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
                 .name("Spicoli")
                 .age(16)
                 .motto("Aloha, Mr Hand")
                 .buildStudent();

其中某些字段可以具有默认值,也可以是可选的。

评论

20赞 ivanceras 2/14/2013
不过我很好奇,为什么我们在使用构建器模式时需要一个构建器类。我在想学生 s1 = new Student().name(“Spicolo”).age(16).motto(“Aloha, Mr Hand);
68赞 Eli Courtwright 2/15/2013
@ivanceras:当类具有必填字段时,这是相关的,并且您不希望能够在无效状态下实例化这些类。所以如果你只是说,那会让你有一个没有名字的学生,这可能很糟糕。如果还不错,那么您的解决方案就可以了。Student s1 = new Student().age(16);
69赞 Jules 2/28/2013
@ivanceras:另一个原因是你可能希望你的类在构造后是不可变的,所以你不希望其中的方法改变它的值。
5赞 Abhijeet Kushe 8/17/2015
@ivanceras:我使用 Builders 做了 3 件事 - 消除了多重参数和流畅的初始化、不可变性,最重要的是,我觉得可以在 build() 方法中验证域对象。如果无效,为什么要创建对象实例。您还可以重载静态工厂方法,如上面的情况 buildFreshman()、buildSenior() 等
0赞 luis.espinal 1/4/2019
这里使用 Builder 模式对于 OP 的要求(默认参数值)来说似乎是多余的。事实上,我根本看不出这如何为原始问题提供答案。
1赞 Nicholas Jordan 9/23/2009 #6

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

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

我认为我们在这里需要做的是解决 null 作为默认值相对于 String one=new String(“”);作为成员变量,然后在分配传递给构造函数的字符串之前检查 null。

在Java中完成的原始,平流层计算机科学的数量非常显着。

C++ 等有供应商库,是的。Java 可以在大型服务器上超越它们,因为它是一个巨大的工具箱。研究静态初始值设定项块,请继续关注我们。

93赞 ebelisle 5/27/2010 #7

不幸的是,是的。

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++类型在编译期间检查它们。

评论

10赞 Michael Francis 10/2/2013
永远不应该使用生产代码。抛出异常。assert
0赞 Clashsoft 2/22/2015
Boolean!= ... 可以写成......booleanBoolean.class.isInstance(p[0]);p[0] instanceof Boolean
8赞 BrainSlugs83 4/19/2015
-1 这真的不是 varargs 的用途。这是一个黑客。-- 在这种情况下,使用重载将更具可读性(这很不幸,因为三个额外的字符比 5 行额外的源代码更具可读性......-- 但 Java 不支持默认参数。
27赞 lythic 7/22/2011 #8

您可以在 Scala 中执行此操作,Scala 运行在 JVM 上并与 Java 程序兼容。http://www.scala-lang.org/

class Foo(var prime: Boolean = false, val rib: String)  {}

评论

68赞 om-nom-nom 4/3/2012
带来全新的语言来获得一个不那么常见的功能?
10赞 destan 11/7/2016
这与OP的问题无关
4赞 hoaz 12/14/2012 #9

它不受支持,但有几个选项,例如使用带有一些语法糖的参数对象模式:

public class Foo() {
    private static class ParameterObject {
        int param1 = 1;
        String param2 = "";
    }

    public static void main(String[] args) {
        new Foo().myMethod(new ParameterObject() {{ param1 = 10; param2 = "bar";}});
    }

    private void myMethod(ParameterObject po) {
    }
}

在此示例中,我们使用默认值进行构造,并在类实例初始化部分中重写它们ParameterObject{ param1 = 10; param2 = "bar";}

19赞 IronWolf 2/18/2013 #10

我可能在这里陈述了显而易见的事实,但为什么不自己简单地实现“默认”参数呢?

public class Foo() {
        public void func(String s){
                func(s, true);
        }
        public void func(String s, boolean b){
                //your code here
        }
}

对于默认值,您将使用

func("my string");

如果您不想使用默认值,则可以使用

func("my string", false);

评论

19赞 Offler 2/18/2013
发帖人问是否可以避免这种(相当丑陋的)图案...... ;-)在更现代的语言(如 c#、Scala)中,你不需要这种额外的重载,它只会创建更多的代码行。在某种程度上,你可以同时使用 varargs (static int max( int... array ) { }),但它们只是一个非常丑陋的解决方法。
2赞 Antony Booth 11/15/2013
重载并不丑陋,并且有很多好处,例如具有不同签名的不同方法调用可以执行不同的功能。//This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } } //Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } }
1赞 The incredible Jan 4/6/2017
@Offler默认参数与“现代语言”无关。20年前,我在Delphi中使用过它们,它们可能已经存在于Turbo Pascal中。
631赞 Vitalii Fedorenko 11/1/2013 #11

有几种方法可以在 Java 中模拟默认参数:

  1. 方法重载。

    void foo(字符串 a, 整数 b) { //... }

    void foo(字符串 a) { foo(a, 0);这里,0 是 b 的默认值 }

    foo(“一个”,2); foo(“一个”);

此方法的局限性之一是,如果有两个相同类型的可选参数,并且可以省略其中任何一个,则该方法不起作用。

  1. 瓦拉格斯。

a) 所有可选参数均为同一类型:

    void foo(String a, Integer... b) {
        Integer b1 = b.length > 0 ? b[0] : 0;
        Integer b2 = b.length > 1 ? b[1] : 0;
        //...
    }

    foo("a");
    foo("a", 1, 2);

b) 可选参数的类型可能不同:

    void foo(String a, Object... b) {
        Integer b1 = 0;
        String b2 = "";
        if (b.length > 0) {
          if (!(b[0] instanceof Integer)) { 
              throw new IllegalArgumentException("...");
          }
          b1 = (Integer)b[0];
        }
        if (b.length > 1) {
            if (!(b[1] instanceof String)) { 
                throw new IllegalArgumentException("...");
            }
            b2 = (String)b[1];
            //...
        }
        //...
    }

    foo("a");
    foo("a", 1);
    foo("a", 1, "b2");

这种方法的主要缺点是,如果可选参数是不同类型的,则会丢失静态类型检查。此外,如果每个参数具有不同的含义,则需要某种方法来区分它们。

  1. 空值。为了解决上述方法的局限性,您可以允许 null 值,然后分析方法主体中的每个参数:

    void foo(字符串 a, 整数 b, 整数 c) { b = b != null ?b : 0; c = c != 空 ?c : 0; //... }

    foo(“a”, null, 2);

现在必须提供所有参数值,但默认值可能为 null。

  1. 可选类。此方法类似于 null,但对具有默认值的参数使用 Java 8 Optional 类:

    void foo(字符串 a,可选 bOpt) { 整数 b = bOpt.orElse(0); //... }

    foo(“a”, 可选.of(2)); foo(“a”, Optional.absent());

    Optional 为调用方显式提供方法协定,但是,人们可能会发现此类签名过于冗长。

  2. 生成器模式。构建器模式用于构造函数,并通过引入单独的 Builder 类来实现:

    class Foo {
        private final String a; 
        private final Integer b;
    
        Foo(String a, Integer b) {
          this.a = a;
          this.b = b;
        }
    
        //...
    }
    
    class FooBuilder {
      private String a = ""; 
      private Integer b = 0;
    
      FooBuilder setA(String a) {
        this.a = a;
        return this;
      }
    
      FooBuilder setB(Integer b) {
        this.b = b;
        return this;
      }
    
      Foo build() {
        return new Foo(a, b);
      }
    }
    
    Foo foo = new FooBuilder().setA("a").build();
    
  3. 地图。当参数数量过多且通常使用默认值时,可以将方法参数作为其名称/值的映射传递:

    void foo(Map<String, Object> 参数) { 字符串 a = “”; 整数 b = 0; 如果 (parameters.containsKey(“a”)) { 如果 (!(parameters.get(“a”) instanceof Integer)) { 抛出新的 IllegalArgumentException(“...”); } a = (字符串)parameters.get(“a”); } else if (parameters.containsKey(“b”)) { //... } //... }

    foo(ImmutableMap.<String, Object>of( “一个”,“一个”, “b”, 2, “d”, “值”));

请注意,您可以结合这些方法中的任何一种来获得理想的结果。

评论

2赞 Celeritas 7/19/2014
很好的解释。我从未见过像这样使用的返回值。对于 5) 做什么?另外,既然(根据定义)构造函数首先被调用并返回一个值,这难道不意味着没有机会被调用吗?return thisFooBuilder().setA("a").build();FooBuilder().setA("a"):
7赞 ADTC 8/27/2014
@Celeritas 返回调用该方法的同一对象(在示例中为 )。这允许在一个语句中链接方法,作用于同一对象:等等,而不是在单独的语句中调用每个方法。return thisFooBuildernew FooBuilder().setA(..).setB(..).setC(..)
3赞 ADTC 8/27/2014
@Celeritas 返回调用该方法的对象。As 未调用,保留默认值。最后,在此对象上调用该方法。该方法创建并返回一个对象,该对象设置为变量 。请注意,该对象未存储在任何变量中。new FooBuilder()FooBuildersetAsetBthis.bbuildFooBuilderbuildFooFoo fooFooBuilder
0赞 Martin Spamer 1/27/2015
注释还可用于创建默认参数,在需要多态集合时最有用。docs.oracle.com/javase/tutorial/java/annotations/declaring.html
0赞 Pellet 9/1/2016
Java 现在在 1.8 中支持可选,无需番石榴:)
3赞 Hamzeh Soboh 11/3/2013 #12

请尝试以下解决方案:

public int getScore(int score, Integer... bonus)
{
    if(bonus.length > 0)
    {
        return score + bonus[0];
    }

    return score;
}
49赞 peterh 11/4/2014 #13

不,但你可以很容易地模仿它们。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是因为它很简单。

评论

11赞 Kolya Ivankov 10/17/2017
C# 默认值表示法的主要思想恰恰是为了避免这种样板编码,并且只有一个构造函数而不是多个构造函数。
1赞 peterh 10/17/2017
@KolyaIvankov 我不懂 C#,但我知道C++推理在哪里是一样的。我不知道哪个更好,但我认为,实际上在 C++/C# 的情况下,编译器生成了相同的样板代码,并且它正在进入最终的二进制文件。
8赞 Kolya Ivankov 10/17/2017
每种编程语言(特别是)都是避免汇编程序样板的一种手段,我错了吗?问题只是它是否提供了方便的功能。
2赞 Kolya Ivankov 10/17/2017
更具体地说:语言是允许我们以可以控制所写内容的方式编写程序的工具,编译是一种告诉机器我们想要从中得到什么的方法。如果一个工具允许我们避免样板,那么它就更有用。实际上,gnavi 问道,他们是否可以精确地避免您建议的样板代码类型作为答案,因为 C# 允许这样做。
1赞 Michael Sims 1/18/2015 #14

我就是这样做的......它可能不如针对您定义的参数使用“可选参数”方便,但它可以完成工作:

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 为我们的参数提供“可选参数”要干净一些,因为我们需要为默认值等编写代码。在这个例子中,我不需要担心这些。是的,我在我的课堂上添加了另一种方法,但从长远来看,以我的拙见,它更容易阅读。

4赞 Tomas Bjerre 6/12/2016 #15

您可以使用 Java Method Invocation Builder 自动生成具有默认值的构建器。

只需将@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);
2赞 Novaterata 7/15/2016 #16

在 Java 8 中工作的类似 https://stackoverflow.com/a/13864910/2323964 方法是使用带有默认 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; }
        });
    }
}
1赞 Umair Khalid 9/1/2016 #17

不,但是我们有函数重载形式的替代方案。

未传递参数时调用

void operation(){

int a = 0;
int b = 0;

} 

传递“A”参数时调用

void operation(int a){

int b = 0;
//code

} 

在参数 B 传递时调用

void operation(int a , int b){
//code
} 
21赞 simhumileco 11/23/2017 #18

,但实现此功能的最简单方法是

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

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

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

或者,您可以使用以下命令代替三元运算符if

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

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

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}
10赞 mrts 11/27/2017 #19

正如 Scala 所提到的,Kotlin 也值得一提。在 Kotlin 中,函数参数也可以有默认值,它们甚至可以引用其他参数:

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
    ...
}

与 Scala 一样,Kotlin 在 JVM 上运行,可以很容易地集成到现有的 Java 项目中。

2赞 AAGD 3/12/2019 #20

我现在花了相当多的时间来弄清楚如何将其与返回值的方法一起使用,到目前为止我还没有看到任何示例,我认为在此处添加此内容可能会很有用:

int foo(int a) {
    // do something with a
    return a;
}

int foo() {
    return foo(0); // here, 0 is a default value for a
}
11赞 Virendra Pal Singh 12/16/2019 #21

Java 不支持它,就像其他语言一样,例如 Kotlin。

0赞 Sobhit Sharma 12/30/2019 #22

您可以使用以下内容 -

public void mop(Integer x) {
  // Define default values
        x = x == null ? 200 : x;
}
23赞 Viktor Taranenko 2/14/2020 #23

而不是使用:

void parameterizedMethod(String param1, int param2) {
    this(param1, param2, false);
}

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

您可以通过使用单个方法来利用 java 的可选功能:

void parameterizedMethod(String param1, int param2, @Nullable Boolean param3) {
    param3 = Optional.ofNullable(param3).orElse(false);
    //use all three parameters here
}

主要区别在于您必须使用包装类而不是原始 Java 类型来允许输入。而不是 ,而不是 等等。nullBooleanbooleanIntegerint

评论

1赞 famfamfam 9/14/2021
我尝试过但仍然需要将 params3 传递到函数中以避免来自 Android Studio 的警告错误
0赞 WurmD 8/12/2022
Nullable 和 Optional 的必要导入是什么?
0赞 Nick Fera 11/17/2022
导入 java.util.Optional;并导入 javax.annotation.Nullable;
1赞 Inês Gomes 7/25/2020 #24

一个想法是使用String... args

public class Sample {
   void demoMethod(String... args) {
      for (String arg : args) {
         System.out.println(arg);
      }
   }
   public static void main(String args[] ) {
      new Sample().demoMethod("ram", "rahim", "robert");
      new Sample().demoMethod("krishna", "kasyap");
      new Sample().demoMethod();
   }
}

输出

ram
rahim
robert
krishna
kasyap

https://www.tutorialspoint.com/Does-Java-support-default-parameter-values-for-a-method 相比

4赞 Tobias 10/20/2020 #25

如果你真的想要,你可以使用以下方法手动检查它:null

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

但是,我强烈建议使用其他东西,例如重载或静态工厂。也许你可以侥幸逃脱,但它可能会导致未经检查的行为。例如,您的代码中可能存在错误,因此您的布尔值永远不会得到值。在这种情况下,您不会得到 .相反,它看起来像是设置为 false,这可能会使调试非常混乱。NullPointerException

3赞 Marco Polo 10/5/2021 #26

构造函数 Like for 方法

static void popuping() {
    popuping("message", "title");
}
static void popuping(String message) {
    popuping(message, "title");
}
static void popuping(String message, String title){
    JOptionPane.showMessageDialog(null, message,
            title, JOptionPane.INFORMATION_MESSAGE);
}
1赞 Legioneroff 8/25/2022 #27

Yes = 使用 Kotlin!)))

这是一个笑话;

0赞 user2498328 12/21/2022 #28

直截了当的答案是否定的。

这些答案已经很老了,主要讨论我们可以拥有的替代方案,即使 java 没有默认方法参数的直接方法。

我们可以通过 java 中的函数式编程轻松处理这种情况。

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

在以下情况下,我们可能需要一个默认参数... 例: 创建一个适用于两个不同对象并返回计算的方法

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,现在我们不能进一步超载,而且有多个这样的方法确实感觉很奇怪。

这时我们可以利用咖喱方法技术。

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

创建 Curried 方法的步骤

  1. 编写一个接受单个参数并返回另一个参数的函数 功能,如下所示。

     Function<Integer,Function<Integer,Integer>> mutiply = a->{
     return  b -> a*b;
     };
    
  2. 让我们简化并理解上述方法。

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

“闭包是一种函数,它在其词法上下文中引用自由变量。” 因此,在本例中,闭包是对变量乘法进行操作时返回的函数,它有一个自由变量 a,该变量具有调用者函数的词法上下文。

  1. 返回 multiply 方法或修复其中一个参数的默认值。

     //multiply is defined in the first step
     mutiplyByTwo = mutiply.apply(2)
    
     mutiplyByThree = mutiply.apply(3);
    
     mutiplyByFour = mutiply.apply(4);;
    

    等等......

  2. 将第二个变量传递给返回的函数以获取结果。

    mutiplyByTwo.apply(2);//results 
    mutiplyByTwo.apply(3);//results 6
    
    
    
     mutiplyByThree.apply(2);//results 6
     mutiplyByThree.apply(3);//results 9
    
     mutiplyByFour.apply(2);//results 8
     mutiplyByFour.apply(3);//results 124
    

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