Java에서 옵션 파라미터를 사용하려면 어떻게 해야 합니까?
옵션 파라미터를 지원하는 사양은 무엇입니까?
Java에서 옵션 파라미터를 시뮬레이트하는 방법은 여러 가지가 있습니다.
메서드 오버로드
void foo(String a, Integer b) {//...}
void foo(String a) { foo(a, 0); // 여기서 0은 b }의 기본값입니다.
fooaa", 2);
이 접근법의 제약사항 중 하나는 같은 유형의 옵션 파라미터가 2개 있고 그 중 하나를 생략할 수 있는 경우에는 동작하지 않는다는 것입니다.
- 바라그스
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");
이 접근법의 주요 단점은 옵션파라미터의 유형이 다른 경우 정적 유형 체크가 손실된다는 것입니다.또한 각 파라미터의 의미가 다른 경우에는 그것들을 구별할 수 있는 방법이 필요합니다.
Null. 이전 접근법의 한계를 해결하려면 null 값을 허용한 다음 메서드 본문의 각 매개 변수를 분석하면 됩니다.
void foo(문자열 a, 정수 b, 정수 c) { b = b != null ?b : 0; c = c != null ? c : 0; //...}
fooaa", null, 2);
여기서 모든 인수 값을 지정해야 하지만 기본 값은 null일 수 있습니다.
옵션 클래스이 접근법은 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.Optional
Java 8 서avaava를 guava java java java 。메서드명은 조금 다릅니다.빌더 패턴빌더 패턴은 컨스트럭터에 사용되며 별도의 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> 매개 변수) {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);
메서드 오버로드 또는 데이터 유형 사용으로 선택적 매개 변수를 만들 수 있습니다.
|*| 메서드 오버로드:
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
'source' 카테고리의 다른 글
C로 문자열을 소문자로 하는 방법은 무엇입니까? (0) | 2022.08.17 |
---|---|
Vuex 상태 업데이트 방법(MEVN 스택) (0) | 2022.08.17 |
Java 8 Stream을 사용하여 일부 클래스 속성에서 목록을 가져오려면 어떻게 해야 합니까? (0) | 2022.08.17 |
세트에서 요소 가져오기 (0) | 2022.08.16 |
왜 Double일까요?음수가 아닌 MIN_VALUE (0) | 2022.08.16 |