Java optionele parameters

Hoe gebruik ik optionele parameters in Java? Welke specificatie ondersteunt optionele parameters?


Antwoord 1, autoriteit 100%

varargs zou dat (in zekere zin) kunnen doen. Verder moeten alle variabelen in de declaratie van de methode worden aangeleverd. Als u wilt dat een variabele optioneel is, kunt u de methode overbelasten met een handtekening waarvoor de parameter niet nodig is.

private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
    ...
}
public void doSomething() {
    doSomething(defaultOptionalFlagValue);
}

Antwoord 2, autoriteit 96%

Er zijn verschillende manieren om optionele parameters in Java te simuleren:

  1. Overbelasting van de methode.

    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");
    

    Een van de beperkingen van deze aanpak is dat het niet werkt als je twee optionele parameters van hetzelfde type hebt en elk ervan kan worden weggelaten.

  2. Varargs.

    a) Alle optionele parameters zijn van hetzelfde type:

    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) Soorten optionele parameters kunnen verschillen:

    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");
    

    Het belangrijkste nadeel van deze aanpak is dat als optionele parameters van verschillende typen zijn, je de statische typecontrole verliest. Bovendien, als elke parameter een andere betekenis heeft, moet je ze op een of andere manier onderscheiden.

  3. Nulls.Om de beperkingen van de vorige benaderingen aan te pakken, kunt u null-waarden toestaan en vervolgens elke parameter in een methode-body analyseren:

    void foo(String a, Integer b, Integer c) {
        b = b != null ? b : 0;
        c = c != null ? c : 0;
        //...
    }
    foo("a", null, 2);
    

    Nu moeten alle argumentwaarden worden opgegeven, maar de standaardwaarden kunnen null zijn.

  4. Optionele klasse.Deze benadering is vergelijkbaar met nulls, maar gebruikt Java 8 Optionele klasse voor parameters die een standaardwaarde hebben:

    void foo(String a, Optional<Integer> bOpt) {
        Integer b = bOpt.isPresent() ? bOpt.get() : 0;
        //...
    }
    foo("a", Optional.of(2));
    foo("a", Optional.<Integer>absent());
    

    Optioneel maakt een methodecontract expliciet voor een beller, maar men kan een dergelijke handtekening te uitgebreid vinden.

    Update: Java 8 bevat de klasse java.util.Optionalout-of-the-box, dus het is om deze specifieke reden niet nodig om guave te gebruiken in Java 8. De methodenaam is een beetje anders.

  5. Builder-patroon.Het builder-patroon wordt gebruikt voor constructeurs en wordt geïmplementeerd door een aparte Builder-klasse te introduceren:

    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();
    
  6. Kaarten.Als het aantal parameters te groot is en de meeste standaardwaarden gewoonlijk worden gebruikt, kunt u methodeargumenten doorgeven als een kaart van hun namen/waarden:

    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")); 
    

    In Java 9 werd deze aanpak eenvoudiger:

       @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"));
    

Houd er rekening mee dat u elk van deze benaderingen kunt combineren om een gewenst resultaat te bereiken.


Antwoord 3, autoriteit 23%

Er zijn optionele parameters bij Java 5.0. Declareer je functie gewoon als volgt:

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

je zou nu kunnen bellen met doSomething();of doSomething(true);.


Antwoord 4, autoriteit 18%

Je kunt zoiets als dit gebruiken:

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

De variabele paramsis optioneel. Het wordt behandeld als een nullable array van Objecten.

Vreemd genoeg kon ik hier niets over vinden in de documentatie, maar het werkt!

Dit is “nieuw” in Java 1.5 en hoger (niet ondersteund in Java 1.4 of eerder).

Ik zie dat gebruiker bhoot dit hieronder ook heeft genoemd.


Antwoord 5, autoriteit 11%

Er zijn geen optionele parameters in Java. Wat u kunt doen, is de functies overbelasten en vervolgens standaardwaarden doorgeven.

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

Antwoord 6, autoriteit 4%

VarArgs en overbelasting zijn genoemd. Een andere optie is een Bloch Builder-patroon, dat er ongeveer zo uitziet:

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

Hoewel dat patroon het meest geschikt zou zijn als je optionele parameters in een constructor nodig hebt.


Antwoord 7, autoriteit 3%

In JDK>1.5 kun je het als volgt gebruiken;

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);
        }
    }
}

Antwoord 8

Je kunt dingen doen door op deze manier methode-overbelasting te gebruiken.

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

U kunt ook @Nullable annotatie gebruiken

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

geef gewoon null door als eerste parameter.

Als u hetzelfde type variabele doorgeeft, kunt u deze gebruiken

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

Antwoord 9

Korte versie:

Met drie stippen:

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); 

(gebaseerd op het antwoord van @VitaliiFedorenko)


Antwoord 10

Overbelasting is prima, maar als er veel variabelen zijn die een standaardwaarde nodig hebben, krijg je het volgende:

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) {  }

Dus ik raad aan om de Variabel argumentgeleverd door Java.


Antwoord 11

Als het een API-eindpunt is, is een elegante manier om “Lente”-annotaties te gebruiken:

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

Merk in dit geval op dat de innerFunc de variabele vereist, en aangezien het geen api-eindpunt is, deze Spring-annotatie niet kan gebruiken om het optioneel te maken.
Referentie: https://www.baeldung.com/spring-request-param


Antwoord 12

Je kunt een klasse gebruiken die ongeveer hetzelfde werkt als een builder om je optionele waarden op deze manier te bevatten.

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);
}

Gebruik zoals

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

Uitvoer is

someString = something, someInt = 5

Als je alle optionele waarden wilt overslaan, moet je het aanroepen als foo(o -> {});of als je wilt, kun je een tweede foo()methode die de optionele parameters niet gebruikt.

Met deze aanpak kunt u optionele waarden in elke volgorde opgeven zonder enige dubbelzinnigheid. Je kunt ook parameters van verschillende klassen hebben, in tegenstelling tot varargs. Deze aanpak zou nog beter zijn als je annotaties en codegeneratie kunt gebruiken om de klasse Options te maken.


Antwoord 13

Java ondersteunt nu optionals in 1.8, ik zit vast met programmeren op Android, dus ik gebruik nulls totdat ik de code kan refactoren om optionele typen te gebruiken.

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

Antwoord 14

Standaardargumenten kunnen niet in Java worden gebruikt. Waar in C #, C++ en Python, kunnen we ze gebruiken.

In Java moeten we 2 methoden (functies) moeten gebruiken in plaats van één met standaardparameters.

Voorbeeld:

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-


Antwoord 15

Dit is een oude vraag Misschien zelfs voordat het daadwerkelijke optionele type werd geïntroduceerd, maar tegenwoordig kun je een paar dingen overwegen:
– Gebruik methode overbelasting
– Gebruik optioneel type dat voordeel heeft van het vermijden van passerende nulls rond
Optioneel type werd geïntroduceerd in Java 8 voordat het meestal wordt gebruikt van derde lib, zoals Google’s Guava. Als u optioneel gebruikt, omdat parameters / argumenten als overmatig gebruik kunnen worden overwogen, omdat het hoofddoel het als een terugkeertijd zou gebruiken.

Ref: https: //itcodehub.blogspot .com / 2019/06 / met behulp van-optionele-type-in-java.html


Antwoord 16

We kunnen optionele parameter maken per methode overbelasting of het gebruik van datatype …

| * | Methode Overbelasting:

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;
}

De gemakkelijkste manier is

|*| DataType… kan een optionele parameter zijn

RetDataType NameFnc(int NamePsgVar, String... stringOpnPsgVar)
{
    if(stringOpnPsgVar.length == 0)  stringOpnPsgVar = DefaultValue; 
    // |* Code Todo *|
    return RetVar;
}


Antwoord 17

Als u van plan bent een interface met meerdere parameters te gebruiken,
men kan het volgende structurele patroongebruiken en toepassen of overschrijven toepassen – een methode gebaseerd op uw vereiste.

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

Other episodes