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

评论

否。但是,Builder模式可以提供帮助。

我真的很想念这个功能。在修改现有代码以为函数或构造函数添加额外参数时,它很有帮助

@Jatin通过Eclipse的“更改方法签名”重构,您可以添加参数并提供现有调用者将使用的默认值。

@ErwinBolwidt谢谢。我正在使用Android Studio,它还可以选择重构方法并提供默认值。非常有用。

@temporary_user_name public MyParameterizedFunction(String param1,int param2)是构造函数,而不是方法,声明。

#1 楼

不,您找到的结构是Java处理它的方式(即使用重载而不是默认参数)。有关构造函数,请参见《有效的Java:编程语言指南》的第1项技巧(请考虑使用静态工厂方法)如果重载变得越来越复杂。对于其他方法,重命名某些情况或使用参数对象会有所帮助。这是当您具有足够的复杂性而难以区分的时候。在一定情况下,您必须使用参数的顺序进行区分,而不仅仅是数字和类型。

评论


那是在2009年,在2015年,任何静态事物都被认为是有害的。现在,强制执行完整且有效的施工合同的类型安全,流畅的Builder实例现在是一个更好的解决方案。

–user177800
2015年12月18日4:27



@JarrodRoberson:静态工厂方法并不比新方法有害。在新代码中始终使用它们。简单值对象的生成器通常是过度设计的结果。

– Lii
16 Jan 22'8:38



@JarrodRoberson:通过编译器强制正确使用的有趣方式,谢谢分享!对以后的帖子的友好建议:对于大多数人来说,300行未注释的源代码可能需要消化很多(毕竟,比编写起来难于阅读而不是编写代码)。再次感谢!

–克里斯蒂安·艾辛格(Christian Aichinger)
16年1月27日在21:55

@JarrodRoberson:很好,期待它!我想交流的内容:作为您博客的读者,一个50行的示例,其中简要介绍了所发生的事情,这将为我提供300多个无上下文的示例。

–克里斯蒂安·艾辛格(Christian Aichinger)
16年1月27日在22:12

@ user177800不同意-如果将静态方法编写为纯函数,则完全可以。当静态函数改变状态时,它们就会变成问题...

–李维·富勒(Levi Fuller)
18年12月18日在3:47

#2 楼

不,但是您可以使用此堆栈溢出答案中所述的构建器模式。

如链接的答案中所述,构建器模式可让您编写类似

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

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

评论


最后是一个不到2页的Builder模式示例。

–nevvermind
2012年11月8日在21:38

不过,我很好奇,为什么在使用构建器模式时需要一个构建器类。我在想Student s1 = new Student()。name(“ Spicolo”)。age(16).motto(“ Aloha,Mr Hand);

– ivanceras
13年2月14日在8:32

@ivanceras:当类具有必填字段并且您不希望能够以无效状态实例化这些类时,这是相关的。因此,如果您只是说Student s1 = new Student()。age(16);那样的话,您就会生出一个没有名字的学生,这可能很糟糕。如果还不错,那么您的解决方案就可以了。

– Eli Courtwright
13年2月14日在18:33

@ivanceras:另一个原因是您可能希望类在构造之后是不可变的,因此您不希望其中的方法更改其值。

–法律
13年2月27日在16:02

@ivanceras:我使用Builders做三件事-消除了多参数和流畅的初始化,不变性,最重要的是我觉得可以在build()方法中验证域对象。为什么创建对象实例无效,还可以重载static在上述情况下,工厂方法如buildFreshman(),buildSenior()等

– Abhijeet Kushe
15年8月16日在22:00

#3 楼

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



方法重载。

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


其中一种此方法的局限性在于,如果您具有两个相同类型的可选参数,并且其中的任何一个都可以省略,则该方法将无效。


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


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


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

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

foo("a", null, 2);


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


可选类。这种方法与null相似,但是对具有默认值的参数使用Java 8 Optional类:

void foo(String a, Optional<Integer> bOpt) {
    Integer b = bOpt.isPresent() ? bOpt.get() : 0;
    //...
}

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


Optional使方法契约对于调用者是显式的,但是,可能会发现这样的签名太冗长。


构建器模式。构建器模式用于构造函数,并通过引入单独的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();



地图。当参数的数量太大并且通常使用大多数默认值时,可以将方法参数作为其名称/值的映射传递:

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



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

评论


很好的解释。我从未见过像这样使用返回值。对于5)这样做的收益是什么?另外,不FooBuilder()。setA(“ a”)。build();因为(根据定义)首先调用构造函数,并且FooBuilder()返回一个值,所以这不意味着.setA(“ a”):没有机会被调用吗?

– Celeletas
14年7月18日在22:37

@Celeritas return会返回调用该方法的同一对象(在示例中为FooBuilder)。这允许在一个作用于同一对象的语句中链接方法:new FooBuilder()。setA(..)。setB(..)。setC(..)等,而不是在单独的语句中调用每个方法。

– ADTC
2014年8月27日在8:44



@Celeritas new FooBuilder()返回一个FooBuilder对象,在该对象上调用setA方法。由于未调用setB,因此this.b保留默认值。最后,在此FooBuilder对象上调用build方法。 build方法创建并返回一个Foo对象,该对象设置为变量Foo foo。请注意,FooBuilder对象没有存储在任何变量中。

– ADTC
2014年8月27日在8:48

注释也可以用于创建默认参数,并且在需要多态集合时最有用。 docs.oracle.com/javase/tutorial/java/annotations/declaring.html

–马丁·斯帕默
15年1月27日在9:47

在两个问题上,对同一答案的投票超过900次。我印象深刻:stackoverflow.com/questions/965690/java-optional-parameters / ...

– AdamMc331
15年11月28日在19:19

#4 楼

可悲的是,没有。

评论


难过吗这样做会引入潜在的歧义功能签名。

–特里
09年6月15日在19:46

@Trey:具有默认参数的语言通常会放弃函数重载,因为这样一来引人注目。因此没有歧义。此外,Scala在2.8中添加了该功能,并以某种方式解决了歧义性问题(因为出于兼容性原因,它们保留了重载)。

– PhiLho
2011年5月24日13:09

我看不到参数默认值如何防止函数重载。例如,C#允许覆盖,也允许默认初始化。似乎是任意选择,而不是限制是原因。

– FlavorScape
13年11月30日在17:43



是的,让我们权衡一下,让编译器做一些额外的工作,而是让我们所有人都写100000重载,从而为我们的库用户提供便利。好主意。

–user562566
14年5月13日在8:02

@ user562566:每当我从事Java项目时,都会给人一种印象,即Java开发人员是按每天产生多少行代码来付费/衡量的

– Mark K Cowan
16-10-16在20:38

#5 楼

不幸的是,是的。

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 ++类型在编译过程中对其进行检查。

评论


聪明,但是varargs(...)仅可用于最终参数,这比支持默认参数的语言所提供的限制更大。

–CurtainDog
2010年5月26日在22:20

与C ++版本相比,这很聪明,但有点混乱

–某处有人
2011年11月4日在18:27

Java肯定需要可选的默认参数,因为C#和其他参数允许...语法很明显,我想他们甚至可以通过编译所有可能的组合就可以相当简单地实现此目的...我无法想象为什么他们没有将其添加到语言中然而!

– jwl
2012年2月23日在23:31

永远不要在生产代码中使用断言。引发异常。

–迈克尔·多斯特(Michael Dorst)
13年10月1日在18:52

-1这真的不是varargs的目的。这是一个hack。 -在这种情况下,使用重载将更具可读性(不幸的是,因为三个额外的字符比五个额外的源代码行更具可读性...)。 -但是Java不支持默认参数。

– BrainSlugs83
15年4月18日在18:43



#6 楼

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

评论


C#默认值表示法的主要思想恰恰是避免这种样板式编码,并且只有一个构造函数而不是许多构造函数。

–科里亚·伊万科夫(Kolya Ivankov)
17-10-17在9:27

@KolyaIvankov我不知道C#,但是我知道C ++的推理是相同的。我不知道有什么更好的方法,但是我认为,实际上对于C ++ / C#,编译器会生成相同的样板代码,并且该代码将进入最终的二进制文件。

–peterh-恢复莫妮卡
17-10-17在9:34

每种编程语言(尤其)都是避免汇编程序样板的一种方式,我错了吗?问题仅在于它是否具有方便的功能。

–科里亚·伊万科夫(Kolya Ivankov)
17-10-17在11:45

第一句话是一个反问。第二句中的“疑问”一词与第一句中的修辞问题无关。

–科里亚·伊万科夫(Kolya Ivankov)
17-10-17在13:44

更具体地讲:语言是使我们能够控制程序编写方式的程序的工具,而编译则是告诉计算机要从中获得什么的一种方法。如果工具允许我们避免样板,则它会更有用。实际上,gnavi询问他们是否可以完全避免您提出的答案的样板代码类型,因为C#允许这样做。

–科里亚·伊万科夫(Kolya Ivankov)
17-10-17在13:50

#7 楼

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

ie

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


评论


带来全新的语言以获得一种不太常见的功能?

–om-nom-nom
2012年4月3日13:59

@ om-nom-nom:Java永远不应该存在。说不使用某个功能就等于没有人需要它,这意味着Java在发明之前并不流行,这意味着Gosling不应该开始设计它。

–Val
2012年6月15日15:17



@Val只是说这就像用大炮射击鸟类

–om-nom-nom
2012年6月15日15:22

与OP的问题无关

–德斯坦
16年11月7日在15:45

在Kotlin也可以。和Groovy。和C#。和Javascript。以及几乎所有其他针对真正的人和问题的语言。

– Spyro
4月29日15:42

#8 楼

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

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


评论


是的,这种方法似乎是其他方法中最好的方法。对于Java来说,采用默认值还是不错的。 Kotlin证明了这是可以做到的,所以我不确定为什么Oracle不会进入现代时代,而是继续设计Java就像1990年代一样。 :D

–雪橇
3月3日14:54



#9 楼

我可能会在这里说明显而易见的内容,但是为什么不自己简单地实现“默认”参数呢?

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


评论


张贴者询问是否可以避免这种(相当丑陋的)模式... ;-)在更现代的语言(如c#,Scala)中,您不需要这种额外的重载,而只需要创建更多的代码行即可。到目前为止,您可以同时使用varargs(静态int max(int ... array){}),但是它们只是一个非常丑陋的解决方法。

–优惠
13年2月18日在14:10

重载并不难看并且有很多好处,例如具有不同签名的不同方法调用可以执行不同的功能。 //这是更好的公共类Foo(){/ *这样做* / public void func(String s){//做某事} / *这与b还有其他作用* / public void func(String s,boolean b } {// b被传递}} //比这个公共类Foo(){/ *除非b = value,否则它会执行其他操作* / public void func(String s,boolean b = value){如果(b){//做其他事情}其他{//做其他事情}}}

– Antony展位
2013年11月14日19:57



好吧,如果有人想要不同的行为。如果唯一的区别是计算等方面的细微变化,那么肯定会浪费创建多个签名的工作。默认值在需要它们的地方很有意义...缺少默认值不应被归类为“无用”要求。

–卡皮尔
2014年1月20日4:47



@Offler默认参数与“现代语言”无关。我20年前在Delphi中使用了它们,它们可能已经存在于Turbo Pascal中。

–令人难以置信的扬
17年4月6日在13:09

我同意Offler,不同意Antony Booth。我发现它不仅难看而且效率很低。诸如ruby或python之类的语言使使用默认参数变得简单。我猜Java需要您做的是找到(和使用)解决方法。显式检查与null似乎是最不丑的选择,因为我也可以从命令行调用它(只是不提供任何内容,然后处理理智的变体);运算符重载方法似乎非常冗长(与null检查相比,至少+3行,如果代码更复杂,则更多行)。

–雪橇
3月3日14:53

#10 楼

代替使用:

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

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


您可以通过一种方法来利用Java的Optional功能:

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


主要区别在于必须使用包装器类而不是原始Java类型来允许null输入。用Boolean代替boolean,用Integer代替int,依此类推。

#11 楼

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

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


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

#12 楼

不会。通常,Java没有太多(任何)语法糖,因为它们试图创建一种简单的语言。

评论


不完全的。令人痛心的事实是,该团队的时间表很紧,没有时间使用语法糖。为什么const和goto会是没有实现的保留关键字? —尤其是const是我很想念的东西—最终是无法替代的,他们知道这一点。 —并且,如果您做出了从不实施goto的明智决定,则无需保留关键字。 —后来在Java团队中,由于基于Label的破坏而作弊,并继续像Pascal goto一样强大。

–马丁
2011-09-18 12:46



“简单,面向对象和熟悉”确实是设计目标-参见oracle.com/technetwork/java/intro-141325.html

– mikera
2013年9月2日在9:27

tomjen说:“不。一般来说,Java没有太多(任何)语法糖,因为它们试图创建一种简单的语言”。因此,您说的是,从C ++中删除许多不必要的功能会使Java成为一种简单的语言,然后告诉我Java为什么具有可变参数方法?为什么有可变参数?如果您只需使用对象数组就不需要了,对吗?因此可以从语言中删除varargs,因为这是不必要的。这将使Java比现在更简单。我对吗?也可以删除重载,因为每种方法的名称都是无限的。

–user2133061
17年8月8日在15:58

这就是为什么我们得到了采用简单语言的spring和东西,并将任何实际的Java项目转换为语法和样板的集群他妈的的原因:-)

–猛兽
19年8月17日在8:54

我对“简单”一词的理解不是强迫开发人员使用样板代码和复杂的解决方法。 myFunction(a,b = false,c = 3),这就是我所说的简单。

– Spyro
4月29日15:44

#13 楼

否。

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

#14 楼

它不受支持,但是有多种选择,例如使用带有一些语法糖的参数对象模式:

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

#15 楼

尝试以下解决方案:

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

    return score;
}


#16 楼

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


#17 楼

Java不像其他语言一样支持它。科特林。

#18 楼

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


#19 楼

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

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

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


#20 楼

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

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


注意,我可以仅使用字符串来调用相同的方法名称,也可以使用字符串和布尔值来调用它。在这种情况下,将cleanClean设置为true将会用提供的字符串替换TextArea中的所有文本。将cleanClean设置为false或将其全部遗漏掉只是将提供的文本追加到TextArea。

还要注意,我没有在这两种方法中重复代码,我只是添加了能够重置的功能实际上,我认为这比Java为参数提供“可选参数”要干净一些,这是通过创建一个仅具有添加的布尔值的同名新方法来创建TextArea的方法。

然后编写默认值等代码。在此示例中,我无需担心任何这些问题。是的,我为班级添加了另一种方法,但是从我的拙见来看,从长远来看,它更容易阅读。

#21 楼

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

,当没有传递任何参数时调用

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
} 


#22 楼

这样会有六个或更多的问题,最终,您到达了静态工厂模式……有关该信息,请参见crypto API。排序很难解释,但是要这样考虑:如果您有构造函数(默认值或其他值),则将状态传播到花括号之外的唯一方法是使用布尔值isValid; (以及null作为默认值v失败的构造函数)或抛出异常,当从现场用户取回它时,它永远不会提供信息。

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

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

用Java完成的原始的,平流层的计算机科学数量非常可观。

C ++等都有供应商库,是的。 Java是一个庞大的工具箱,因此可以在大型服务器上超越它们。学习静态初始化程序块,与我们在一起。

#23 楼

一种想法是使用来自https://www.tutorialspoint.com/Does-Java-support-default-parameter-values-for-的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

方法

#24 楼

如果确实需要,可以使用null手动进行检查:
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
    if(param3 == null) {
        param3 = false;
    }
}

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

#25 楼

您可以使用以下代码-

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