Java 中的可选参数 | Java Debug 笔记

标签: java 参数 java | 发表时间:2021-05-13 08:40 | 作者:村雨遥
出处:https://juejin.cn/backend

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接

问题

如何使用 Java 中的可选参数?可选参数有什么规范么?

回答

回答 1

一定程度上来讲, varargs (即长度可变的参数)可以做到这一点。除此之外,必须提供方法声明中的所有变量。如果想让变量是可选的,那么可以通过重载的方式,此时重载的方法是不带参数的。

   private boolean defaultOptionalFlagValue = true;

public void doSomething(boolean optionalFlag) {
    ...
}

public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}
复制代码

回答 2

可以通过以下几种方式来模拟 Java 中的可选参数:

  1. 方法重载
   void foo(String a, Integer b) {
    //...
}

void foo(String a) {
    foo(a, 0); // b 的默认值为 0
}

foo("a", 2);
foo("a");
复制代码

该方法存在的局限性是:如果有两个类型相同的可选参数,且其中任意一个都可以忽略,那么它就会失效。

  1. 长度可变的参数
  • 所有可选参数类型相同;
   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);
复制代码
  • 可选参数类型可能不同;
   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(String a, Integer b, Integer c) {
    b = b != null ? b : 0;
    c = c != null ? c : 0;
    //...
}

foo("a", null, 2);
复制代码

此时必须提供所有的参数值,但是他们的缺省值可以为 null

  1. 可选类

该方法类似于使用空值的方法,但 Java 8 中允许使用可选类作为参数默认值;

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

foo("a", Optional.of(2));
foo("a", Optional.absent());
复制代码
  1. 构造器模式

通过使用构造器,同时引入一个单独的 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();
复制代码
  1. Maps

当参数过多,且大多数默认值通常都被使用时,可以将方法参数作为它们的名称/值得映射传递给它们;

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

foo(ImmutableMap.of(
    "a", "a",
    "b", 2, 
    "d", "value")); 
复制代码

Java 9 中,使用如下方法可以简化该操作:

   @SuppressWarnings("unchecked")
static  T getParm(Map map, String key, T defaultValue)
{
    return (map.containsKey(key)) ? (T) map.get(key) : defaultValue;
}

void foo(Map parameters) {
    String a = getParm(parameters, "a", "");
    int b = getParm(parameters, "b", 0);
    // d = ...
}

foo(Map.of("a","a",  "b",2,  "d","value"));
复制代码

以上就是 6 种使用可选参数的一些方法了,你可以通过对他们进行有机组合,从而达到你想要的结果。

回答 3

自 Java 1.5 开始,就存在可选参数,你可以像如下方式来声明你的方法:

   public void doSomething(boolean... optionalFlag) {
    //  默认为 "false"
    //boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
复制代码

然后你就既可以调用 doSomething(),也可以调用 doSomething(true) 了。

出处

文章翻译自 Stack Overflow: Java optional parameters

相关 [java 参数 java] 推荐:

java socket参数详解:BackLog

- - 开源软件 - ITeye博客
 java socket参数详解:BackLog. 输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数. 如果队列满时收到连接指示,则拒绝该连接. backlog参数必须是大于 0 的正值. 如果传递的值等于或小于 0,则假定为默认值. 经过测试这个队列是按照 FIFO(先进先出)的原则.

Java 中的可选参数 | Java Debug 笔记

- - 掘金 后端
本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看. 如何使用 Java 中的可选参数. 一定程度上来讲, varargs (即长度可变的参数)可以做到这一点. 除此之外,必须提供方法声明中的所有变量. 如果想让变量是可选的,那么可以通过重载的方式,此时重载的方法是不带参数的.

Java虚拟机(JVM)参数简介

- - ITeye博客
Java虚拟机(JVM)参数简介. 在Java、J2EE大型应用中,JVM非标准参数的配置直接关系到整个系统的性能. JVM非标准参数指的是JVM底层的一些配置参数,这些参数在一般开发中默认即可,不需要任何配置. 但是在生产环境中,为了提高性能,往往需要调整这些参数,以求系统达到最佳新能. 另外这些参数的配置也是影响系统稳定性的一个重要因素,相信大多数Java开发人员都见过“OutOfMemory”类型的错误.

Java可变参数的性能分析

- - Java译站
可变长参数列表是Java 5中的一个新特性. 如果方法需要传入多个同类型参数的话,这个功能就非常有用. 比如说,Java 5之前如果要写一个方法来将所有入参打印到控制台上的话,它的代码会是这样的:. Java 5增加了对可变参数的支持. 这个方法现在看起来就简单多了(译注:这里看起来简单难道不是因为新的for循环.

Java 6 JVM参数配置说明

- - Java - 编程语言 - ITeye博客
-XX:+

java参数传递机制浅析

- - CSDN博客编程语言推荐文章
java语言中,参数的传递只有一种机制,那就是 值传递. 下面将通过几个例子来说明java中的参数传递机制,这些例子基本涵盖了所有参数传递的情况. 结果当然很显然都是10,因为基本数据类型传递的是值的一份拷贝(副本),对副本操作不影响原始值.     2.1.对参数重新赋值:. 方法中的参数只是原始对象的一份拷贝,更准确的讲是地址的一份拷贝,故而对其进行重新赋值并不会影响原始对象.

JAVA性能优化 - IBMJDKJVM参数设置

- - 编程语言 - ITeye博客
 本文将描述IBM JDK下常用参数的设置.   -Xms:最小堆大小.   -Xmx:最大堆大小.   -Xminf and -Xmaxf:GC(垃圾回收)之后可用空间的最小值最大值.   -Xmine and -Xmaxe:堆增长的最小最大值.   -Xmint and -Xmaxt:垃圾回收占时间整个运行时间的比例,默认是5%.

Java 6 JVM参数选项大全(中文版)

- LightingMan - 淘宝JAVA中间件团队博客
本文是基于最新的SUN官方文档Java SE 6 Hotspot VM Options 编写的译文. 主要介绍JVM中的非稳态选项及其使用说明. 为了让读者明白每个选项的含义,作者在原文基础上补充了大量的资料. 希望这份文档,对正在研究JVM参数的朋友有帮助. 另外,考虑到本文档是初稿,如有描述错误,敬请指正.

java 三个点号...的含义-可变参数

- - ITeye博客
  在java 1.5 SE后,引入了三个点号"...",表示参数是可以有无数个的意思. // 参数都是int类型的,所以可以用foreach. 已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

Java中的锁(Locks in Java)

- - 并发编程网 - ifeve.com
原文链接 作者:Jakob Jenkov 译者:申章 校对:丁一. 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂. 因为锁(以及其它更高级的线程同步机制)是由synchronized同步块的方式实现的,所以我们还不能完全摆脱synchronized关键字( 译者注:这说的是Java 5之前的情况).