जवाबों:
varargs ऐसा कर सकता है (एक तरह से)। इसके अलावा, विधि की घोषणा में सभी चर आपूर्ति की जानी चाहिए। यदि आप एक चर को वैकल्पिक बनाना चाहते हैं, तो आप हस्ताक्षर का उपयोग करके विधि को अधिभारित कर सकते हैं जिसके लिए पैरामीटर की आवश्यकता नहीं है।
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}
जावा में वैकल्पिक मापदंडों को अनुकरण करने के कई तरीके हैं:
विधि अधिभार।
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");
इस दृष्टिकोण की सीमाओं में से एक यह है कि यह काम नहीं करता है यदि आपके पास एक ही प्रकार के दो वैकल्पिक पैरामीटर हैं और उनमें से किसी को भी छोड़ा जा सकता है।
Varargs।
क) सभी वैकल्पिक पैरामीटर एक ही प्रकार के हैं:
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");
इस दृष्टिकोण का मुख्य दोष यह है कि यदि वैकल्पिक पैरामीटर विभिन्न प्रकार के हैं तो आप स्थैतिक प्रकार की जाँच खो देते हैं। इसके अलावा, यदि प्रत्येक पैरामीटर के अलग-अलग अर्थ हैं, तो आपको उन्हें अलग करने के लिए किसी तरह की आवश्यकता है।
Nulls। पिछले दृष्टिकोणों की सीमाओं को संबोधित करने के लिए आप शून्य मानों की अनुमति दे सकते हैं और फिर विधि बॉडी में प्रत्येक पैरामीटर का विश्लेषण कर सकते हैं:
void foo(String a, Integer b, Integer c) {
b = b != null ? b : 0;
c = c != null ? c : 0;
//...
}
foo("a", null, 2);
अब सभी तर्क मूल्यों को प्रदान किया जाना चाहिए, लेकिन डिफ़ॉल्ट वाले अशक्त हो सकते हैं।
वैकल्पिक वर्ग। यह दृष्टिकोण शून्य के समान है, लेकिन डिफ़ॉल्ट मान वाले पैरामीटर के लिए जावा 8 वैकल्पिक वर्ग का उपयोग करता है:
void foo(String a, Optional<Integer> bOpt) {
Integer b = bOpt.isPresent() ? bOpt.get() : 0;
//...
}
foo("a", Optional.of(2));
foo("a", Optional.<Integer>absent());
वैकल्पिक एक फोन करने वाले के लिए एक विधि अनुबंध को स्पष्ट करता है, हालांकि, किसी को इस तरह के हस्ताक्षर भी मिल सकते हैं।
अपडेट: जावा 8 में क्लास java.util.Optional
आउट-ऑफ-द-बॉक्स शामिल है, इसलिए जावा 8 में इस विशेष कारण के लिए अमरूद का उपयोग करने की कोई आवश्यकता नहीं है। हालांकि विधि का नाम थोड़ा अलग है।
बिल्डर पैटर्न। बिल्डर पैटर्न का उपयोग कंस्ट्रक्टरों के लिए किया जाता है और एक अलग बिल्डर वर्ग शुरू करके इसे लागू किया जाता है:
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 = (Integer)parameters.get("a");
}
if (parameters.containsKey("b")) {
//...
}
//...
}
foo(ImmutableMap.<String, Object>of(
"a", "a",
"b", 2,
"d", "value"));
जावा 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"));
कृपया ध्यान दें कि आप वांछनीय परिणाम प्राप्त करने के लिए इनमें से किसी भी दृष्टिकोण को जोड़ सकते हैं।
a
वेरिएबल एक स्ट्रिंग है (कास्ट सही है)।
जावा 5.0 के साथ वैकल्पिक पैरामीटर है। बस अपने कार्य को इस तरह घोषित करें:
public void doSomething(boolean... optionalFlag) {
//default to "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
आप अभी doSomething();
या इसके साथ कॉल कर सकते doSomething(true);
हैं।
doSomething() { doSomething(true); }
से निपटने के लिए कोई अतिभारित नहीं, कोई अस्पष्टता नहीं
आप कुछ इस तरह का उपयोग कर सकते हैं:
public void addError(String path, String key, Object... params) {
}
params
चर वैकल्पिक है। इसे वस्तुओं की एक अशक्त सारणी के रूप में माना जाता है।
अजीब बात है, मैं इस बारे में कुछ भी दस्तावेज में नहीं मिल सका, लेकिन यह काम करता है!
यह जावा 1.5 और उसके बाद का "नया" है (जावा 1.4 या उससे पहले समर्थित नहीं है)।
मैं देखता हूं कि उपयोगकर्ता ने इसका उल्लेख नीचे किया है।
दुर्भाग्य से जावा सीधे डिफ़ॉल्ट मापदंडों का समर्थन नहीं करता है।
हालाँकि, मैंने जावाबीन एनोटेशन का एक सेट लिखा है, और उनमें से एक निम्नलिखित की तरह डिफ़ॉल्ट मापदंडों का समर्थन करता है:
protected void process(
Processor processor,
String item,
@Default("Processor.Size.LARGE") Size size,
@Default("red") String color,
@Default("1") int quantity) {
processor.process(item, size, color, quantity);
}
public void report(@Default("Hello") String message) {
System.out.println("Message: " + message);
}
एनोटेशन प्रोसेसर इसे ठीक से समर्थन करने के लिए विधि अधिभार उत्पन्न करता है।
Http://code.google.com/p/javadude/wiki/Annotations देखें
Http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample पर पूरा उदाहरण
VarArgs और ओवरलोडिंग का उल्लेख किया गया है। एक अन्य विकल्प एक बिल्डर पैटर्न है, जो कुछ इस तरह दिखाई देगा:
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){}
बस पहले पैरामीटर के रूप में शून्य पास करें।
यदि आप एक ही प्रकार के चर से गुजर रहे हैं तो आप इसका उपयोग कर सकते हैं
public void load(String name...){}
ओवरलोडिंग ठीक है, लेकिन अगर बहुत सारे चर हैं जिन्हें डिफ़ॉल्ट मान की आवश्यकता है, तो आप इसके साथ समाप्त हो जाएंगे:
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) { }
इसलिए मैं सुझाव दूंगा कि जावा द्वारा उपलब्ध चर तर्क का उपयोग किया जाए। यहाँ स्पष्टीकरण के लिए एक लिंक है।
आप एक ऐसे वर्ग का उपयोग कर सकते हैं जो एक बिल्डर की तरह काम करता है ताकि आपके वैकल्पिक मान इस तरह हों।
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()
तरीका जो वैकल्पिक मापदंडों को नहीं लेता है।
इस दृष्टिकोण का उपयोग करके, आप बिना किसी अस्पष्टता के किसी भी क्रम में वैकल्पिक मान निर्दिष्ट कर सकते हैं। आपके पास भिन्न वर्ग के मापदंडों के विपरीत भी हो सकते हैं। यह दृष्टिकोण और भी बेहतर होगा यदि आप विकल्प वर्ग बनाने के लिए एनोटेशन और कोड पीढ़ी का उपयोग कर सकते हैं।
जावा अब 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
}
जावा में डिफ़ॉल्ट तर्कों का उपयोग नहीं किया जा सकता है। जहाँ C #, C ++ और Python में, हम उनका उपयोग कर सकते हैं ।।
जावा में, हमें डिफ़ॉल्ट मापदंडों के साथ एक के बजाय 2 विधियों (कार्यों) का उपयोग करना होगा।
उदाहरण:
Stash(int size);
Stash(int size, int initQuantity);
यह एक पुराना प्रश्न है, भले ही वास्तविक वैकल्पिक प्रकार पेश किए जाने से पहले लेकिन इन दिनों आप कुछ बातों पर विचार कर सकते हैं: - विधि का उपयोग ओवरलोडिंग - वैकल्पिक प्रकार का उपयोग करें, जो वैकल्पिक प्रकार से गुजरने से बचने का लाभ जावा 8 में आमतौर पर उपयोग होने से पहले पेश किया गया था। Google के अमरूद जैसे तीसरे पक्ष के दायित्व से। वैकल्पिक के रूप में मापदंडों / तर्कों का उपयोग करना अति-उपयोग के रूप में माना जा सकता है क्योंकि मुख्य उद्देश्य इसे वापसी समय के रूप में उपयोग करना था।
Ref: https://itcodehub.blogspot.com/2019/06/using-optional-type-in-java.html
हम विधि अधिभार या DataType का उपयोग करके वैकल्पिक पैरामीटर बना सकते हैं ...
| * | विधि अधिभार:
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;
}
सबसे आसान तरीका है
| * | DataType ... वैकल्पिक पैरामीटर हो सकता है
RetDataType NameFnc(int NamePsgVar, String... stringOpnPsgVar)
{
if(stringOpnPsgVar.length == 0) stringOpnPsgVar = DefaultValue;
// |* Code Todo *|
return RetVar;
}
RetDtaTyp
... गंभीरता से? क्या RetDataType
टाइप करना बहुत मुश्किल है?
यदि आप कई मापदंडों के साथ एक इंटरफ़ेस का उपयोग करने की योजना बना रहे हैं , तो एक निम्नलिखित संरचनात्मक पैटर्न का उपयोग कर सकता है और लागू कर सकता है या लागू कर सकता है - आपकी आवश्यकता के आधार पर एक विधि ।
public abstract class Invoker<T> {
public T apply() {
return apply(null);
}
public abstract T apply(Object... params);
}
यदि यह एक एपीआई समापन बिंदु है, तो एक सुंदर तरीका "स्प्रिंग" एनोटेशन का उपयोग करना है:
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false, defaultValue = "hello") String id) {
return innerFunc(id);
}
इस मामले में ध्यान दें कि इनरफंक को वैरिएबल की आवश्यकता होगी, और चूंकि यह एपि समापन बिंदु नहीं है, इसलिए इसे वैकल्पिक बनाने के लिए इस स्प्रिंग एनोटेशन का उपयोग नहीं किया जा सकता है। संदर्भ: https://www.baeldung.com/spring-request-param