我遇到了一些具有以下结构的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中有几种模拟默认参数的方法:

方法重载。void foo(字符串a,整数b){//...}void foo(字符串a){foo(a,0);//这里,0是b的默认值}foo(“a”,2);foo(“a”);这种方法的一个限制是,如果您有两个相同类型的可选参数,并且可以省略其中的任何一个,那么它就不起作用。变量。a) 所有可选参数的类型相同:void foo(字符串a,整数…b){整数b1=b.length>0?b[0]:0;整数b2=b.length>1?b[1]:0;//...}foo(“a”);foo(“a”,1,2);b) 可选参数的类型可能不同:void foo(字符串a,对象…b){整数b1=0;字符串b2=“”;如果(b.length>0){if(!(b[0]instanceof Integer)){抛出新的IllegalArgumentException(“…”);}b1=(整数)b[0];}如果(b.长度>1){if(!(b[1]instanceof String)){抛出新的IllegalArgumentException(“…”);}b2=(字符串)b[1];//...}//...}foo(“a”);foo(“a”,1);foo(“a”,1,“b2”);这种方法的主要缺点是,如果可选参数的类型不同,则会丢失静态类型检查。此外,如果每个参数具有不同的含义,则需要一些方法来区分它们。Null。为了解决前面方法的局限性,可以允许空值,然后分析方法体中的每个参数:void foo(字符串a、整数b、整数c){b=b!=无效的b:0;c=c!=无效的c:0;//...}foo(“a”,null,2);现在必须提供所有参数值,但默认值可能为空。可选类。这种方法类似于null,但对具有默认值的参数使用Java 8 Optional类:void foo(字符串a,可选<整数>bOpt){整数b=bOpt.isPresent()?bOpt.get():0;//...}foo(“a”,可选,第(2)项);foo(“a”,可选。<Integer>absent());可选使方法契约对调用方显式,但是,可能会发现这种签名过于冗长。生成器模式。生成器模式用于构造函数,通过引入单独的生成器类来实现:Foo类{private final字符串a;私有最终整数b;Foo(字符串a,整数b){这个.a=a;此.b=b;}//...}类FooBuilder{private字符串a=“”;私有整数b=0;FooBuilder setA(字符串a){这个.a=a;返回此;}FooBuilder集合b(整数b){此.b=b;返回此;}Foo build(){返回新的Foo(a,b);}}Foo Foo=新建FooBuilder().setA(“a”).build();地图。当参数的数量太大并且大多数参数通常使用默认值时,可以将方法参数作为其名称/值的映射传递:void foo(Map<String,Object>参数){字符串a=“”;整数b=0;if(parameters.containsKey(“a”)){if(!(parameters.get(“a”)instanceof Integer)){抛出新的IllegalArgumentException(“…”);}a=(字符串)参数.get(“a”);}否则如果(parameters.containsKey(“b”)){//... }//...}foo(ImmutableMap.<String,Object>of(“a”、“a”,“b”,2,“d”、“值”);

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

其他回答

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

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

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

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

C++等等都有供应商库,是的。由于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);
}

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

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

类似的方法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; }
        });
    }
}

这可以在Scala中实现,Scala在JVM上运行,并与Java程序兼容。http://www.scala-lang.org/

i.e.

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