Java는 디폴트 파라미터 값을 지원합니까?
다음과 같은 구조를 가진 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는 이러한 구문을 지원합니까?이 2단계 구문이 바람직한 이유가 있습니까?
아니요, 찾은 구조는 Java가 처리하는 방식입니다(기본 파라미터 대신 오버로드 사용).
컨스트럭터에 대해서는 오버로드가 복잡해지는 경우 효과적인 Java: Programming Language Guide의 Item 1 힌트(컨스트럭터 대신 정적 팩토리 메서드 고려)를 참조하십시오.다른 방법으로는 일부 케이스의 이름을 변경하거나 파라미터 개체를 사용하면 도움이 됩니다.이 때 복잡성이 충분하기 때문에 구별이 어렵습니다.확실한 경우는 숫자와 유형뿐만 아니라 파라미터의 순서를 사용하여 구별해야 하는 경우입니다.
아니요, 하지만 이 스택 오버플로 응답에 설명된 대로 Builder 패턴을 사용할 수 있습니다.
링크된 답변에서 설명한 바와 같이 Builder Pattern을 사용하면 다음과 같은 코드를 작성할 수 있습니다.
Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
.name("Spicoli")
.age(16)
.motto("Aloha, Mr Hand")
.buildStudent();
일부 필드에는 기본값을 설정할 수도 있고 옵션일 수도 있습니다.
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");이 접근법의 제약사항 중 하나는 같은 유형의 옵션 파라미터가 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(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());옵션의 경우, 메서드 계약이 발신자에게 명시적으로 되어 있습니다만, 그러한 시그니처는 너무 상세하게 기술되어 있는 경우가 있습니다.
빌더 패턴빌더 패턴은 컨스트럭터에 사용되며 별도의 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"));
바람직한 결과를 얻기 위해 이러한 방법을 조합할 수 있습니다.
슬프게도, 아닙니다.
아쉽게도 그렇습니다.
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++ 구문에서는 파라미터 목록의 끝에 디폴트 파라미터만 사용할 수 있습니다.
구문 이외에도 실행 시간 유형에서 전달된 기본 파라미터가 있는지 확인하고 C++ 유형에서 컴파일 중에 해당 파라미터를 확인하는 차이가 있습니다.
아뇨, 하지만 아주 쉽게 따라 할 수 있어요.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++의 경우는 알 수 있습니다.그렇습니다.모호한 케이스가 생성될 수 있지만, 이러한 문제는 쉽게 해결할 수 있습니다.그것은 단순히 자바에서 개발되지 않았다. 아마도 크리에이터들이 C++처럼 훨씬 단순한 언어를 원했기 때문일 것이다. 만약 그들이 옳다면, 또 다른 의문이다.하지만 대부분의 사람들은 그가 Java를 사용하는 이유는 단순하기 때문이라고 생각하지 않습니다.
이는 JVM에서 실행되며 Java 프로그램과 호환되는 Scala에서 수행할 수 있습니다.http://www.scala-lang.org/
예.
class Foo(var prime: Boolean = false, val rib: String) {}
사용하는 대신:
void parameterizedMethod(String param1, int param2) {
this(param1, param2, false);
}
void parameterizedMethod(String param1, int param2, boolean param3) {
//use all three parameters here
}
다음 한 가지 방법으로 java의 옵션 기능을 이용할 수 있습니다.
void parameterizedMethod(String param1, int param2, @Nullable Boolean param3) {
param3 = Optional.ofNullable(param3).orElse(false);
//use all three parameters here
}
은 "Java"를 허용하려면 입니다.nulldiscloss.discloss.Booleanboolean,Integerint기타 등등.
아니요, 하지만 가장 간단한 구현 방법은 다음과 같습니다.
public myParameterizedFunction(String param1, int param2, Boolean param3) {
param3 = param3 == null ? false : param3;
}
public myParameterizedFunction(String param1, int param2) {
this(param1, param2, false);
}
또는 3진 연산자 대신if:
public myParameterizedFunction(String param1, int param2, Boolean param3) {
if (param3 == null) {
param3 = false;
}
}
public myParameterizedFunction(String param1, int param2) {
this(param1, param2, false);
}
여기서 당연한 말을 하고 있을 수도 있지만, "기본값" 파라미터를 직접 구현해 보는 것은 어떨까요?
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);
스칼라가 언급했듯이, 코틀린도 언급할 가치가 있다.Kotlin의 함수 파라미터는 기본값을 가질 수 있으며 다른 파라미터도 참조할 수 있습니다.
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
...
}
Scala와 마찬가지로 Kotlin은 JVM 상에서 실행되며 기존 Java 프로젝트에 쉽게 통합할 수 있습니다.
아니요. 자바어에는 통사설탕이 별로 없어요. 왜냐하면 그들은 간단한 언어를 만들려고 했기 때문이죠.
아니요.
스마트 기본값을 가진 개체를 전달하여 동일한 동작을 수행할 수 있습니다.하지만 다시 한 번 말씀드리지만, 어떤 사건이 다가오느냐에 따라 다르죠.
java에서는 ex의 다른 언어처럼 지원되지 않습니다.코틀린.
하실 수 .null:
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
if(param3 == null) {
param3 = false;
}
}
하지만 과부하나 정적 공장 같은 다른 것을 사용하는 것이 좋습니다.어쩌면 당신은 이 일을 피할 수 있을지 모르지만, 예상치 못한 행동으로 이어질 수 있습니다.예를 들어 코드에 오류가 있어서 부울 값을 얻지 못할 수 있습니다., 여러분은 , 신, 신, 신, 신, 신, 습, 습이 나오지 않습니다.NullPointerException대신 false로 설정되어 있는 것처럼 보여 디버깅이 매우 혼란스러울 수 있습니다.
지원되지 않지만 파라미터 오브젝트 패턴과 몇 가지 구문 sugar를 함께 사용하는 등 몇 가지 옵션이 몇 가지 옵션이 있습니다.
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[ Instance ]섹션에서 .{ param1 = 10; param2 = "bar";}
다음 솔루션을 사용해 보십시오.
public int getScore(int score, Integer... bonus)
{
if(bonus.length > 0)
{
return score + bonus[0];
}
return score;
}
Java 메서드 호출 작성기를 사용하여 기본값으로 작성기를 자동으로 생성할 수 있습니다.
그냥 @GenerateMethod 추가클래스 또는 인터페이스에 대한 Invocation Builder 및 기본값인 메서드의 파라미터에 대한 @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);
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; }
});
}
}
값을 반환하는 메서드에서 이 기능을 사용하는 방법을 알아보는 데 오랜 시간이 걸렸지만, 지금까지 예시를 보지 못했습니다. 여기에 이 기능을 추가하면 도움이 될 것 같습니다.
int foo(int a) {
// do something with a
return a;
}
int foo() {
return foo(0); // here, 0 is a default value for a
}
이렇게 해서...정의된 파라미터에 대해 '옵션 인수'를 사용하는 것만큼 편리하지는 않지만 작업을 수행할 수 있습니다.
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 내의 모든 텍스트가 지정된 문자열로 대체됩니다.weepClean을 false로 설정하거나 모두 생략하면 제공된 텍스트가 TextArea에 추가됩니다.
또한 두 가지 메서드에서 코드를 반복하는 것이 아니라 추가된 부울로만 동일한 이름을 가진 새 메서드를 생성하여 TextArea를 리셋할 수 있는 기능을 추가할 뿐입니다.
이것은 Java가 파라미터에 대해 '옵션 인수'를 제공한 경우보다 조금 더 명확하다고 생각합니다.기본값 등을 코드화할 필요가 있기 때문입니다.이 예에서는 그런 걱정은 하지 않아도 됩니다.네, 저는 수업에 다른 방법을 추가했지만, 제 겸손한 의견으로는 장기적으로 읽기가 더 쉬워요.
아니요, 하지만 함수의 과부하 형태에 대한 대안이 있습니다.
매개 변수가 전달되지 않을 때 호출됨
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
}
이와 같은 문제가 6개 이상 있습니다.결국, 정적인 공장 패턴에 도달합니다.crypto API 를 참조해 주세요.설명하기는 어렵지만 다음과 같이 생각해 주십시오.기본값 또는 그 외의 컨스트럭터가 있는 경우, 컬리 괄호를 넘어 상태를 전파하는 유일한 방법은 boolean isValid;(null과 함께 기본값 v failed constructor) 또는 필드 사용자로부터 반환할 때 전혀 도움이 되지 않는 예외를 던지는 것입니다.
코드 수정 젠장, 난 수천 개의 라인 컨스트럭터를 쓰고 내가 필요한 걸 해.isValid at object construction(즉, 2라인 컨스트럭터)을 사용하고 있는 것을 알 수 있습니다만, 어떤 이유에서인지, 저는 정적 공장 패턴으로 이행하고 있습니다.메서드 호출에서는 아직 sync() 문제가 있지만 디폴트는 더 나은 대체가 가능합니다(안전합니다).
여기서 필요한 것은 null의 문제를 string 1=new String("") 디폴트값으로 처리하고 멤버 변수로 null을 체크한 후 컨스트럭터에 전달된 문자열을 할당하는 것입니다.
자바에서 행해진 성층권 컴퓨터 과학은 놀라울 정도로 많습니다.
C++ 등에는 벤더 lib가 있습니다.Java는 거대한 툴박스이기 때문에 대규모 서버에서 이를 능가할 수 있습니다.정적 이니셜라이저 블록을 연구하고 정신 차려요
한 가지 아이디어는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
https://www.tutorialspoint.com/Does-Java-support-default-parameter-values-for-a-method 에서
메서드와 같은 컨스트럭터
static void popuping() {
popuping("message", "title");
}
static void popuping(String message) {
popuping(message, "title");
}
static void popuping(String message, String title){
JOptionPane.showMessageDialog(null, message,
title, JOptionPane.INFORMATION_MESSAGE);
}
다음을 사용할 수 있습니다.
public void mop(Integer x) {
// Define default values
x = x == null ? 200 : x;
}
언급URL : https://stackoverflow.com/questions/997482/does-java-support-default-parameter-values
'programing' 카테고리의 다른 글
| Mac에서 .c 파일을 컴파일하려면 어떻게 해야 합니까? (0) | 2022.08.29 |
|---|---|
| Vuex unregister Module의 기능은 무엇입니까? (0) | 2022.08.29 |
| Vue Chart.js 구성 요소가 렌더링되지 않음 (0) | 2022.08.29 |
| VisualStudio2010년 명령줄 인수를 전달하면? (0) | 2022.08.29 |
| C의 i++와 (i)++의 차이 (0) | 2022.08.29 |