source

Java에서 옵션 파라미터를 사용하려면 어떻게 해야 합니까?

factcode 2022. 8. 17. 23:43
반응형

Java에서 옵션 파라미터를 사용하려면 어떻게 해야 합니까?

옵션 파라미터를 지원하는 사양은 무엇입니까?

Java에서 옵션 파라미터를 시뮬레이트하는 방법은 여러 가지가 있습니다.

  1. 메서드 오버로드

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

    void foo(String a) { foo(a, 0); // 여기서 0은 b }의 기본값입니다.

    fooaa", 2);

이 접근법의 제약사항 중 하나는 같은 유형의 옵션 파라미터가 2개 있고 그 중 하나를 생략할 수 있는 경우에는 동작하지 않는다는 것입니다.

  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. 이전 접근법의 한계를 해결하려면 null 값을 허용한 다음 메서드 본문의 각 매개 변수를 분석하면 됩니다.

    void foo(문자열 a, 정수 b, 정수 c) { b = b != null ?b : 0; c = c != null ? c : 0; //...}

    fooaa", null, 2);

여기서 모든 인수 값을 지정해야 하지만 기본 값은 null일 수 있습니다.

  1. 옵션 클래스이 접근법은 null과 비슷하지만 기본값을 가진 파라미터에 Java 8 Optional 클래스를 사용합니다.

    void foo(String a, 옵션 bOpt) { 정수 b = bOpt.isPresent() ? bOpt.get() : 0; //...}

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

    옵션의 경우, 메서드 계약이 발신자에게 명시적으로 되어 있습니다만, 그러한 시그니처는 너무 상세하게 기술되어 있는 경우가 있습니다.

    "Java 8"이 되어 있습니다.java.util.OptionalJava 8 서avaava를 guava java java java 。메서드명은 조금 다릅니다.

  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> 매개 변수) {String a = " , Integer b = 0 ; if ( parameters . contains Key ( " a ) ) { if ( ! ( parameters . getaa ) instance of Integer } { throw new Ifal Argument }예외("..."); } a = (Integer) parameters.get("a"); } if (parameters.containsKey("b")) {/... } //...}

    foo(Imputable Map)<문자열, 오브젝트>/("a", "a", "b", "2, "d", "값");

    Java 9에서는 이 접근법이 쉬워졌습니다.

    @SuppressWarnings("unchecked")
    static <T> T getParm(Map<String, Object> map, String key, T defaultValue) {
      return (map.containsKey(key)) ? (T) map.get(key) : defaultValue;
    }
    
    void foo(Map<String, Object> parameters) {
      String a = getParm(parameters, "a", "");
      int b = getParm(parameters, "b", 0);
      // d = ...
    }
    
    foo(Map.of("a","a",  "b",2,  "d","value"));
    

바람직한 결과를 얻기 위해 이러한 방법을 조합할 수 있습니다.

varargs는 (어떤 면에서는) 그렇게 할 수 있습니다.그 외에는 메서드 선언에 있는 모든 변수를 제공해야 합니다.변수를 옵션인 경우 매개 변수가 필요 없는 서명을 사용하여 메서드를 오버로드할 수 있습니다.

private boolean defaultOptionalFlagValue = true;

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

public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}

Java 5.0에는 옵션 파라미터가 있습니다.다음과 같이 기능을 선언합니다.

public void doSomething(boolean... optionalFlag) {
    //default to "false"
    //boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}

로 할 수 .doSomething(); ★★★★★★★★★★★★★★★★★」doSomething(true);

다음과 같은 것을 사용할 수 있습니다.

public void addError(String path, String key, Object... params) { 
}

params입니다.객체의 늘 배열로 취급됩니다.

이상하게도 문서에서는 아무것도 찾을 수 없었습니다만, 동작하고 있습니다!

이는 Java 1.5 이상에서는 "새로운" 버전입니다(Java 1.4 이전 버전에서는 지원되지 않습니다).

사용자 부트도 아래에 언급되어 있는 것을 알 수 있습니다.

Java에는 옵션 파라미터가 없습니다.할 수 있는 것은 함수를 오버로드하고 기본값을 전달하는 것입니다.

void SomeMethod(int age, String name) {
    //
}

// Overload
void SomeMethod(int age) {
    SomeMethod(age, "John Doe");
}

VarArgs 및 오버로드에 대해 언급했습니다.또 다른 옵션은 다음과 같은 Bloch Builder 패턴입니다.

 MyObject my = new MyObjectBuilder().setParam1(value)
                                 .setParam3(otherValue)
                                 .setParam6(thirdValue)
                                 .build();

그러나 이 패턴은 생성자에서 선택적 매개 변수가 필요한 경우에 가장 적합합니다.

JDK > 1.5 에서는, 다음과 같이 사용할 수 있습니다.

public class NewClass1 {

    public static void main(String[] args) {

        try {
            someMethod(18); // Age : 18
            someMethod(18, "John Doe"); // Age & Name : 18 & John Doe
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void someMethod(int age, String... names) {

        if (names.length > 0) {
            if (names[0] != null) {
                System.out.println("Age & Name : " + age + " & " + names[0]);
            }
        } else {
            System.out.println("Age : " + age);
        }
    }
}

이렇게 메서드 오버로드를 사용하여 작업을 수행할 수 있습니다.

 public void load(String name){ }

 public void load(String name,int age){}

또한 @Nullable 주석을 사용할 수 있습니다.

public void load(@Nullable String name,int age){}

첫 번째 파라미터로 null을 전달합니다.

동일한 유형 변수를 전달할 경우 이 옵션을 사용할 수 있습니다.

public void load(String name...){}

쇼트 버전:

점 3개 사용:

public void foo(Object... x) {
    String first    =  x.length > 0 ? (String)x[0]  : "Hello";
    int duration    =  x.length > 1 ? Integer.parseInt((String) x[1])     : 888;
}   
foo("Hii", ); 
foo("Hii", 146); 

(@Vitalii Fedorenko의 답변에 근거합니다)

오버로드도 괜찮지만 기본값을 필요로 하는 변수가 많으면 다음과 같이 됩니다.

public void methodA(A arg1) {  }    
public void methodA(B arg2) {  }
public void methodA(C arg3) {  }
public void methodA(A arg1, B arg2) {  }
public void methodA(A arg1, C arg3) {  }
public void methodA(B arg2, C arg3) {  }
public void methodA(A arg1, B arg2, C arg3) {  }

따라서 Java에서 제공하는 변수 인수를 사용하는 것이 좋습니다.

API 엔드포인트인 경우 "Spring" 주석을 사용하는 것이 좋습니다.

@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false, defaultValue = "hello") String id) { 
    return innerFunc(id);
}

이 경우 innerFunc는 변수를 필요로 하며 API 엔드포인트가 아니기 때문에 이 스프링 주석을 사용하여 변수를 옵션으로 만들 수 없습니다.참고 자료: https://www.baeldung.com/spring-request-param

작성기처럼 작동하는 클래스를 사용하여 다음과 같은 선택적 값을 포함할 수 있습니다.

public class Options {
    private String someString = "default value";
    private int someInt= 0;
    public Options setSomeString(String someString) {
        this.someString = someString;
        return this;
    }
    public Options setSomeInt(int someInt) {
        this.someInt = someInt;
        return this;
    }
}

public static void foo(Consumer<Options> consumer) {
    Options options = new Options();
    consumer.accept(options);
    System.out.println("someString = " + options.someString + ", someInt = " + options.someInt);
}

사용법

foo(o -> o.setSomeString("something").setSomeInt(5));

출력은

someString = something, someInt = 5

모든 옵션 값을 건너뛰려면 다음과 같이 불러야 합니다.foo(o -> {});또는 원하는 경우 두 번째를 생성할 수 있습니다.foo()선택적 매개 변수를 사용하지 않는 메서드입니다.

이 방법을 사용하면 임의의 순서로 임의의 값을 지정할 수 있습니다.또한 varargs와 달리 다른 클래스의 매개 변수를 가질 수도 있습니다.주석 및 코드 생성을 사용하여 옵션 클래스를 만들 수 있는 경우 이 방법은 훨씬 더 좋습니다.

Java는 1.8에서 옵션 기능을 지원하며, 저는 안드로이드의 프로그래밍에 얽매여 있기 때문에 옵션 타입을 사용하기 위해 코드를 리팩터링할 수 있을 때까지 늘을 사용하고 있습니다.

Object canBeNull() {
    if (blah) {
        return new Object();
    } else {
        return null;
    }
}

Object optionalObject = canBeNull();
if (optionalObject != null) {
    // new object returned
} else {
    // no new object returned
}

이것은 실제 옵션 타입이 도입되기 전부터 오래된 질문입니다만, 최근에는 몇 가지 사항을 고려할 수 있습니다.- 메서드 오버로드 사용 - 옵션 타입을 사용하는 것은 Java 8에서 도입되었습니다.옵션 타입은 보통 Google의 Guava와 같은 서드파티 lib에서 사용되기 전에 도입되었습니다.파라미터/인수로 옵션 사용을 하는 것은 반환시간으로 사용하는 것이 주된 목적이었기 때문에 과도한 사용으로 간주할 수 있습니다.

참고 자료: https://itcodehub.blogspot.com/2019/06/using-optional-type-in-java.html

Java에서는 기본 인수를 사용할 수 없습니다.C#, C++ 및 Python에서는 사용할 수 있습니다.

Java에서는 기본 파라미터가 있는 메서드(함수)가 아닌 2개의 메서드(함수)를 사용해야 합니다.

예:

Stash(int size); 

Stash(int size, int initQuantity);

http://parvindersingh.webs.com/apps/forums/topics/show/8856498-java-how-to-set-default-parameters-values-like-c-

메서드 오버로드 또는 데이터 유형 사용으로 선택적 매개 변수를 만들 수 있습니다.

|*| 메서드 오버로드:

RetDataType NameFnc(int NamePsgVar)
{
    // |* Code Todo *|
    return RetVar;
}

RetDataType NameFnc(String NamePsgVar)
{
    // |* Code Todo *|
    return RetVar;
}

RetDataType NameFnc(int NamePsgVar1, String NamePsgVar2)
{
    // |* Code Todo *|
    return RetVar;
}

가장 쉬운 방법은

|*| 데이터 타입...옵션 파라미터가 될 수 있습니다.

RetDataType NameFnc(int NamePsgVar, String... stringOpnPsgVar)
{
    if(stringOpnPsgVar.length == 0)  stringOpnPsgVar = DefaultValue; 

    // |* Code Todo *|
    return RetVar;
}

여러 파라미터를 가진 인터페이스를 사용할 계획인 경우 다음 구조 패턴을 사용하여 요건을 기반으로 한 방법인 적용을 구현하거나 재정의할 수 있습니다.

public abstract class Invoker<T> {
    public T apply() {
        return apply(null);
    }
    public abstract T apply(Object... params);
}

언급URL : https://stackoverflow.com/questions/965690/how-do-i-use-optional-parameters-in-java

반응형