Java支持默认参数值吗?

发布于 2024-07-24 04:41:58 字数 452 浏览 7 评论 0原文

我遇到了一些具有以下结构的 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支持这种语法吗? 有什么理由可以解释为什么这种两步语法更可取吗?

I came across some Java code that had the following structure:

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

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

I know that in C++ I can assign a parameter a default value. For example:

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

Does Java support this kind of syntax? Are there any reasons why this two step syntax is preferable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

薄荷港 2024-07-31 04:41:58

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

对于构造函数,请参阅有效的 Java:编程语言指南 第 1 项提示(考虑静态工厂方法而不是构造函数)
如果重载变得复杂。 对于其他方法,重命名某些案例或使用参数对象可能会有所帮助。

当你的复杂性足够高时,区分就变得很困难。 一个明确的情况是,您必须使用参数的顺序来区分,而不仅仅是数字和类型。

No, the structure you found is how Java handles it, (that is, with overloading instead of default parameters).

For constructors, See Effective Java: Programming Language Guide's Item 1 tip (Consider static factory methods instead of constructors)
if the overloading is getting complicated. For other methods, renaming some cases or using a parameter object can help.

This is when you have enough complexity that differentiating is difficult. A definite case is where you have to differentiate using the order of parameters, not just number and type.

如果没有 2024-07-31 04:41:58

否,但您可以使用构建器模式,如这个堆栈溢出答案

如链接答案中所述,构建器模式允许您编写代码,

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

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

No, but you can use the Builder Pattern, as described in this Stack Overflow answer.

As described in the linked answer, the Builder Pattern lets you write code like

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

in which some fields can have default values or otherwise be optional.

洋洋洒洒 2024-07-31 04:41:58

Java 中模拟默认参数的方法有多种:

  1. 方法重载。

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

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

    foo("a", 2);
    foo(“a”);

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

  1. Varargs。

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. 空值。为了解决以前方法的局限性,您可以允许空值,然后分析方法主体中的每个参数:

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

    foo("a", null, 2);

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

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

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

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

    Optional 使方法契约对于调用者来说是明确的,但是,人们可能会发现这样的签名过于冗长。

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

    类 Foo { 
          私有最终字符串a;  
          私有最终整数 b; 
    
          Foo(字符串 a, 整数 b) { 
            这个.a = a; 
            这个.b = b; 
          } 
    
          //... 
      } 
    
      类 FooBuilder { 
        私有字符串a =“”;  
        私有整数 b = 0; 
    
        FooBuilder setA(字符串a) { 
          这个.a = a; 
          返回这个; 
        } 
    
        FooBuilder setB(整数 b) { 
          这个.b = b; 
          返回这个; 
        } 
    
        Foo 构建(){ 
          返回新的 Foo(a, b); 
        } 
      } 
    
      Foo foo = new FooBuilder().setA("a").build(); 
      
  3. Maps。 当参数数量过多且对于大多数情况时其中通常使用默认值,您可以将方法参数作为其名称/值的映射传递:

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

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

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

There are several ways to simulate default parameters in Java:

  1. Method overloading.

    void foo(String a, Integer b) {
    //...
    }

    void foo(String a) {
    foo(a, 0); // here, 0 is a default value for b
    }

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

One of the limitations of this approach is that it doesn't work if you have two optional parameters of the same type and any of them can be omitted.

  1. Varargs.

a) All optional parameters are of the same type:

    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) Types of optional parameters may be different:

    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");

The main drawback of this approach is that if optional parameters are of different types you lose static type checking. Furthermore, if each parameter has different meaning you need some way to distinguish them.

  1. Nulls. To address the limitations of the previous approaches you can allow null values and then analyse each parameter in a method body:

    void foo(String a, Integer b, Integer c) {
    b = b != null ? b : 0;
    c = c != null ? c : 0;
    //...
    }

    foo("a", null, 2);

Now all arguments values must be provided, but the default ones may be null.

  1. Optional class. This approach is similar to nulls, but uses Java 8 Optional class for parameters that have a default value:

    void foo(String a, Optional bOpt) {
    Integer b = bOpt.orElse(0);
    //...
    }

    foo("a", Optional.of(2));
    foo("a", Optional.absent());

    Optional makes a method contract explicit for a caller, however, one may find such signature too verbose.

  2. Builder pattern. The builder pattern is used for constructors and is implemented by introducing a separate Builder class:

    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. Maps. When the number of parameters is too large and for most of them default values are usually used, you can pass method arguments as a map of their names/values:

    void foo(Map<String, Object> parameters) {
    String a = "";
    Integer b = 0;
    if (parameters.containsKey("a")) {
    if (!(parameters.get("a") instanceof Integer)) {
    throw new IllegalArgumentException("...");
    }
    a = (String)parameters.get("a");
    } else if (parameters.containsKey("b")) {
    //...
    }
    //...
    }

    foo(ImmutableMap.<String, Object>of(
    "a", "a",
    "b", 2,
    "d", "value"));

Please note that you can combine any of these approaches to achieve a desirable result.

离旧人 2024-07-31 04:41:58

可悲的是没有。

Sadly, no.

血之狂魔 2024-07-31 04:41:58

不幸的是,是的。

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[]{}

为每个调用生成 a 的感觉如何。

对于多个可默认参数:

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

Unfortunately, yes.

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

could be written in Java 1.5 as:

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

But whether or not you should depend on how you feel about the compiler generating a

new Boolean[]{}

for each call.

For multiple defaultable parameters:

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

could be written in Java 1.5 as:

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;
}

This matches C++ syntax, which only allows defaulted parameters at the end of the parameter list.

Beyond syntax, there is a difference where this has run time type checking for passed defaultable parameters and C++ type checks them during compile.

遇见了你 2024-07-31 04:41:58

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

No, but you can very easily emulate them. What in C++ was:

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

In Java, it will be an overloaded function:

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);
}

Earlier was mentioned, that default parameters caused ambiguous cases in function overloading. That is simply not true, we can see in the case of the C++: yes, maybe it can create ambiguous cases, but these problem can be easily handled. It simply wasn't developed in Java, probably because the creators wanted a much simpler language as C++ was - if they had right, is another question. But most of us don't think he uses Java because of its simplicity.

万劫不复 2024-07-31 04:41:58

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

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

You can do this is in Scala, which runs on the JVM and is compatible with Java programs.
http://www.scala-lang.org/

i.e.

class Foo(var prime: Boolean = false, val rib: String)  {}
深巷少女 2024-07-31 04:41:58

而不是使用:

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 类型来允许 null 输入。Boolean 代替 booleanInteger 代替 int 等等。

Instead of using:

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

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

You could utilize java's Optional functionality by having a single method:

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

The main difference is that you have to use wrapper classes instead of primitive Java types to allow null input.Boolean instead of boolean, Integer instead of int and so on.

初相遇 2024-07-31 04:41:58

,但实现此目的的最简单方法是:

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);
}

No, but the simplest way to implement this is:

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

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

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}

or instead of the ternary operator, you can use if:

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

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

public myParameterizedFunction(String param1, int param2) {

    this(param1, param2, false);
}
水晶透心 2024-07-31 04:41:58

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

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);

I might be stating the obvious here but why not simply implement the "default" parameter yourself?

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

for the default, you would either use

func("my string");

and if you wouldn't like to use the default, you would use

func("my string", false);
念三年u 2024-07-31 04:41:58

java 不支持它,而其他语言则不支持它。 科特林。

It is not supported in java as in other language for ex. Kotlin.

岁月打碎记忆 2024-07-31 04:41:58

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

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

与 Scala 一样,Kotlin 运行在 JVM 上,可以轻松集成到现有 Java 项目中。

As Scala was mentioned, Kotlin is also worth mentioning. In Kotlin function parameters can have default values as well and they can even refer to other parameters:

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

Like Scala, Kotlin runs on the JVM and can be easily integrated into existing Java projects.

不疑不惑不回忆 2024-07-31 04:41:58

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

No. In general Java doesn't have much (any) syntactic sugar, since they tried to make a simple language.

仙女 2024-07-31 04:41:58

不。

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

No.

You can achieve the same behavior by passing an Object which has smart defaults. But again it depends what your case is at hand.

少女七分熟 2024-07-31 04:41:58

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

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 =“酒吧”;}

It is not supported but there are several options like using parameter object pattern with some syntax sugar:

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) {
    }
}

In this sample we construct ParameterObject with default values and override them in class instance initialization section { param1 = 10; param2 = "bar";}

陪你搞怪i 2024-07-31 04:41:58

您可以使用 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);

You may use Java Method Invocation Builder to automatically generate the builder with default values.

Just add @GenerateMethodInvocationBuilder to the class, or interface, and the @Default to parameters in methods where you want default values. A builder will be generated at compile time, using the default values that you specified with your annotations.

@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;
 }
}

And then you can invoke the methods.

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

Or set any of the default values to something else.

CarService instance = new CarService();
String carsByFilter = CarServiceGetCarsByFilterBuilder.getCarsByFilter()//
  .withColor(Color.YELLOW)//
  .invoke(instance);
为你拒绝所有暧昧 2024-07-31 04:41:58

如果您确实愿意,可以使用 null 手动检查它:

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

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

If you really want to, you can check it manually by using null:

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

However i heavily recommend using something else, like overloading or a static factory. Maybe you can get away with this, but it can lead to unexcspected behavior. For example you could have an error in your code, so that your boolean never gets a value. In this case you would not get a NullPointerException. Instead it will look like it was set to false, which can be very confusing to debug.

往日 2024-07-31 04:41:58

尝试这个解决方案:

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

    return score;
}

Try this solution:

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

    return score;
}
匿名。 2024-07-31 04:41:58

类似于 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);
}

constructor like for method

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);
}
老旧海报 2024-07-31 04:41:58

在 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; }
        });
    }
}

A similar approach to https://stackoverflow.com/a/13864910/2323964 that works in Java 8 is to use an interface with default getters. This will be more whitespace verbose, but is mockable, and it's great for when you have a bunch of instances where you actually want to draw attention to the parameters.

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; }
        });
    }
}
可爱咩 2024-07-31 04:41:58

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

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

int foo() {
    return foo(0); // here, 0 is a default value for a
}

I've now spent quite some time to figure out how to use this with methods that return values, and I haven't seen any examples so far, I thought it might be useful to add this here:

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

int foo() {
    return foo(0); // here, 0 is a default value for a
}
橙味迷妹 2024-07-31 04:41:58

这就是我所做的...它可能不如对定义的参数使用“可选参数”那么方便,但它完成了工作:

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

This is how I did it ... it's not as convenient perhaps as having an 'optional argument' against your defined parameter, but it gets the job done:

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");
}

Notice I can invoke the same method name with either just a string or I can invoke it with a string and a boolean value. In this case, setting wipeClean to true will replace all of the text in my TextArea with the provided string. Setting wipeClean to false or leaving it out all together simply appends the provided text to the TextArea.

Also notice I am not repeating code in the two methods, I am merely adding the functionality of being able to reset the TextArea by creating a new method with the same name only with the added boolean.

I actually think this is a little cleaner than if Java provided an 'optional argument' for our parameters since we would need to then code for default values etc. In this example, I don't need to worry about any of that. Yes, I have added yet another method to my class, but it's easier to read in the long run in my humble opinion.

长梦不多时 2024-07-31 04:41:58

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

未传递参数时

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
} 

NO, But we have alternative in the form of function overloading.

called when no parameter passed

void operation(){

int a = 0;
int b = 0;

} 

called when "a" parameter was passed

void operation(int a){

int b = 0;
//code

} 

called when parameter b passed

void operation(int a , int b){
//code
} 
英雄似剑 2024-07-31 04:41:58

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

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

我认为我们在这里需要做的是解决 null 作为默认值的问题相对于某些东西 String one=new String(""); 作为成员变量,然后在将字符串传递给构造函数之前检查是否为 null。

用 Java 完成的原始计算机科学数量非常惊人。

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

There are half a dozen or better issues such as this, eventually, you arrive at the static factory pattern ... see the crypto API for that. Sort difficult to explain, but think of it this way: If you have a constructor, default or otherwise, the only way to propagate state beyond the curly braces is either to have a Boolean isValid; ( along with the null as default value v failed constructor ) or throw an exception which is never informative when getting it back from field users.

Code Correct be damned, I write thousand line constructors and do what I need. I find using isValid at object construction - in other words, two-line constructors - but for some reason, I am migrating to the static factory pattern. I just seem you can do a lot if you in a method call, there are still sync() issues but defaults can be 'substituted' better ( safer )

I think what we need to do here is address the issue of null as default value vis-a-vis something String one=new String(""); as a member variable, then doing a check for null before assigning string passed to the constructor.

Very remarkable the amount of raw, stratospheric computer science done in Java.

C++ and so on has vendor libs, yes. Java can outrun them on large scale servers due to it's a massive toolbox. Study static initializer blocks, stay with us.

秉烛思 2024-07-31 04:41:58

一种想法是使用

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();
   }
}

String...args输出

ram
rahim
robert
krishna
kasyap

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

One idea is to use 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();
   }
}

Output

ram
rahim
robert
krishna
kasyap

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

一曲爱恨情仇 2024-07-31 04:41:58

您可以使用以下内容 -

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

You can use the following-

public void mop(Integer x) {
  // Define default values
        x = x == null ? 200 : x;
}
萌能量女王 2024-07-31 04:41:58

直接的答案是否定的。

这些答案相当古老,主要讨论即使 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 的默认值,但它将是固定的。 如果我们想要乘以三怎么办,现在我们不能进一步重载它,而且拥有多个这样的方法确实感觉很奇怪。

这时我们就可以利用方法柯里化技术。

柯里化方法是将多参数函数转换为多个函数(每个函数接受一个参数)的方法。

创建柯里化方法的步骤

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

     函数<整数,函数<整数,整数>>>   乘法 = a->{ 
       返回b->   a*b; 
       }; 
      
  2. 让我们简化并理解上面的方法。

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

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

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

     //multiply在第一步中定义 
       mutilyByTwo = mutily.apply(2) 
    
       mutiplyByThree = mutiply.apply(3); 
    
       mutiplyByFour = mutiply.apply(4);; 
      

    等等……

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

    mutiplyByTwo.apply(2);//结果  
      mutilyByTwo.apply(3);//结果6 
    
    
    
       mutilyByThree.apply(2);//结果6 
       mutilyByThree.apply(3);//结果 9 
    
       mutilyByFour.apply(2);//结果8 
       mutilyByFour.apply(3);//结果 124 
      

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

The Straight answer is no.

These answers are pretty old and mainly discuss the alternatives we can have even if java doesn't have a straight way of the default method parameter.

we can deal with this scenario easily with functional Programming in java.

we can utilize the method currying of java functional programming and I think it can be best utilized for such scenarios where we need to have default parameters.

we may need a default parameter in the following situations...
Example:
Create a method that works on Two different objects and returns the computation

int mutiply(int a,int b){

      return a*b;

  }

if we want to have a method to get multiply by 2, we will have to Override the method like below

int mutiply(int a){

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

  }

Above, 2 is a default value for b, but it's going to be fixed. what if we want to have multiplied by three, now we cannot overload this further and it does feel odd to have multiple methods like this.

This is when we can utilize the method currying technique.

method Currying is the way of converting multi-parameter functions into multiple functions each accepting a single parameter.

Steps to create a Curried method

  1. Write a function that accepts a single parameter and returns another
    function, like below.

     Function<Integer,Function<Integer,Integer>> mutiply = a->{
     return  b -> a*b;
     };
    
  2. Let's Simplify and understand the above method.

The Above method accepts only One integer Argument and returns another function with one parameter a as the default value and b as a variable. In case you are confused and start thinking how the method can use a variable from the caller function and don’t know about closures …

"A closure is a function that refers to a free variable in its lexical context."
So here, in this case, closure is the returned function when operated on variable multiply and it has a free variable a that has the lexical context of the caller function.

  1. Return the multiply method or fix the default value for one of the parameters.

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

    And so on …

  2. Pass the second variable to the returned function to get the result.

    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
    

You can find my original post here ... https://www.linkedin.com/pulse/can-we-have-default-method-parameter-java-rajat-singh/?trackingId=yW84I1fzT6WGStrNPAWn4w%3D%3D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文