Skulle Java-metoden argumenter brukes for å returnere flere verdier?

stemmer
26

Siden argumenter sendt til en metode i Java punkt til de opprinnelige datastrukturer i den som ringer metode, gjorde sine designere har tenkt for dem å brukes for å returnere flere verdier, som er normen i andre språk som C?

Eller er dette en farlig misbruk av Java generelle eiendom som variabler er pekere?

Publisert på 07/04/2009 klokken 05:10
kilden bruker
På andre språk...                            


9 svar

stemmer
2

Du kan ikke virkelig returnere flere verdier, men du kan passere gjenstander til en metode og har metoden mutere disse verdiene. Det er helt lovlig. Merk at du ikke kan passere et objekt i og ha selve objektet bli en annen gjenstand. Det er:

private void myFunc(Object a) {
    a = new Object();
}

vil resultere i midlertidig og lokalt å endre verdien av a, men dette vil ikke endre verdien av den som ringer, for eksempel fra:

Object test = new Object();
myFunc(test);

Etter myfunc kommer tilbake, vil du ha gamle Object og ikke den nye.

Legal (og ofte motløs) er noe som dette:

private void changeDate(final Date date) {
    date.setTime(1234567890L);
}

Jeg plukket Datefor en grunn. Dette er en klasse som folk allment enig skulle aldri ha vært foranderlig. Den metoden ovenfor vil endre den interne verdien av en Dategjenstand som du sender til den. Denne typen kode er lovlig når det er helt klart at metoden vil mutere eller konfigurere eller endre det som blir vedtatt i.

MERK: Vanligvis er det sagt at en metode skal gjøre ett disse tingene:

  • Returnere tomrom og mutere de inngående gjenstander (for eksempel Collections.sort()), eller
  • Returnere noen beregning og ikke muterer innkommende gjenstander i det hele tatt (som Collections.min()), eller
  • Returnere en "visning" av innkommende objekt, men ikke endre den innkommende objekt (som Collections.checkedList()eller Collections.singleton())
  • Mutere en innkommende objekt og returnere den ( Collectionsikke har et eksempel, men StringBuilder.append()er et godt eksempel).

Metoder som mutere innkommende gjenstander og returnere en egen returverdi er ofte gjør for mange ting.

Svarte 07/04/2009 kl. 05:16
kilden bruker

stemmer
5

Se denne RFE lansert tilbake i 1999:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4222792

Jeg tror ikke hensikten var å aldri tillate det i Java-språket, hvis du trenger å returnere flere verdier du trenger for å kapsle dem i et objekt.

Ved hjelp av språk som Scala men du kan gå tilbake tupler, se:

http://www.artima.com/scalazine/articles/steps.html

Du kan også bruke Generics i Java for å gå tilbake et par objekter, men det er omtrent det AFAIK.

EDIT: tupler

Bare for å legge til litt mer på dette. Jeg har tidligere gjennomført en Pair i prosjekter på grunn av mangel i JDK. Link til implementering min er her:

http://pbin.oogly.co.uk/listings/viewlistingdetail/5003504425055b47d857490ff73ab9

Merk, det er ikke en hashCode eller lik denne, som trolig bør legges.

Jeg kom også over dette mens du gjør noen undersøkelser i dette spørsmål som gir tuppel funksjonalitet:

http://javatuple.com/

Den lar deg opprette Pair inkludert andre typer tupler.

Svarte 07/04/2009 kl. 05:18
kilden bruker

stemmer
0

Det er sikkert metoder som modifiserer en gjenstand føres inn som en parameter ( se java.io.Reader.read (byte [] buffer) som et eksempel, men jeg har ikke sett parametre brukt som et alternativ til en returverdi, spesielt med multiple parametere. det kan teknisk fungere, men det er ikke-standard.

Svarte 07/04/2009 kl. 05:29
kilden bruker

stemmer
15

For lenge siden hadde jeg en samtale med Ken Arnold (en gang medlem av Java lag), dette ville ha vært på den første Java En konferanse sannsynligvis, så 1996. Han sa at de skulle tenke på å legge til flere returverdier, slik at du kan skrive noe sånt som:

x, y = foo();

Den anbefalte måten å gjøre det da, og nå, er å lage en klasse som har flere data medlemmer og returnere det i stedet.

Basert på det, og andre kommentarer fra folk som jobbet på Java, vil jeg si at hensikten er / var at du returnerer en forekomst av en klasse i stedet for å endre de argumenter som ble vedtatt i.

Dette er vanlig praksis (som er ønsket av C-programmerere til å endre argumentene ... til slutt de ser Java måte å gjøre det vanligvis. Bare tenk på det som å returnere en struct. :-)

(Edit basert på følgende kommentar)

Jeg leser en fil og generering av to matriser, av typen String og int fra den, plukke ett element for både fra hver linje. Jeg ønsker å returnere dem begge til en funksjon som kaller det som en fil for å dele på denne måten.

Jeg tror, ​​hvis jeg forstå deg riktig, tht jeg ville sannsynligvis gjøre soemthing som dette:

// could go with the Pair idea from another post, but I personally don't like that way
class Line
{
    // would use appropriate names
    private final int intVal;
    private final String stringVal;

    public Line(final int iVal, final String sVal)
    {
        intVal    = iVal;
        stringVal = sVal;
    }

    public int getIntVal()
    {
        return (intVal);
    }

    public String getStringVal()
    {
        return (stringVal);
    }

    // equals/hashCode/etc... as appropriate
}

og så har din metode som dette:

public void foo(final File file, final List<Line> lines)
{
    // add to the List.
}

og deretter ringe det slik:

{
    final List<Line> lines;

    lines = new ArrayList<Line>();
    foo(file, lines);
}
Svarte 07/04/2009 kl. 05:40
kilden bruker

stemmer
0

Det er ikke generelt ansett fryktelig god praksis, men det er svært sporadiske tilfeller i JDK der dette er gjort. Se på 'biasRet' parameter av View.getNextVisualPositionFrom () og relaterte fremgangsmåter, for eksempel: det er faktisk en endimensjonal matrise som blir fylt med en "ekstra returverdi".

Så hvorfor gjøre dette? Vel, bare for å spare deg for å måtte lage en ekstra definisjon klasse for "annen ekstra returverdi". Det er rotete, uelegant, dårlig design, ikke-objekt-orientert, blah blah. Og vi har alle gjort det fra tid til annen ...

Svarte 07/04/2009 kl. 06:03
kilden bruker

stemmer
5

Jeg skulle ønske det var en Pair<E,F>klasse i JDK, hovedsakelig på grunn av dette. Det er Map<K,V>.Entry, men å skape en forekomst var alltid en stor smerte.

Nå bruker jeg com.google.common.collect.Maps.immutableEntrynår jeg trenger enPair

Svarte 07/04/2009 kl. 06:33
kilden bruker

stemmer
7

Etter min mening, hvis vi snakker om en offentlig metode, bør du lage en egen klasse som representerer en returverdi. Når du har en egen klasse:

  • det tjener som en abstraksjon (dvs. en Pointklasse istedenfor rekke av to Longs)
  • hvert felt har et navn
  • kan gjøres uforanderlige
  • gjør utviklingen av API mye enklere (dvs. hva om retur tre i stedet for to verdier, endre type enkelte felt etc.)

Jeg vil alltid velge å returnere et nytt eksempel, i stedet for å faktisk endre en verdi vedtatt i. Det virker mye klarere for meg og favoriserer uforanderlighet.

På den annen side, hvis det er en intern metode, antar jeg noe av det følgende kan brukes:

  • en matrise ( new Object[] { "str", longValue })
  • en liste ( Arrays.asList(...)avkastning uforanderlig liste)
  • par / tuppel klasse, slik som denne
  • statisk indre klasse, med offentlige felt

Likevel, jeg foretrekker det siste alternativet, som er utstyrt med en passende konstruktør. Det gjelder spesielt hvis du finner deg selv å returnere samme tuppel fra mer enn ett sted.

Svarte 07/04/2009 kl. 08:54
kilden bruker

stemmer
0

Vanligvis hva Eddie sa, men jeg vil legge til én:

  • Mutere en av de innkommende gjenstander, og returnere en statuskode. Dette bør vanligvis bare brukes til argumenter som er eksplisitt buffere, som Reader.read (char [] cbuf).
Svarte 07/04/2009 kl. 22:04
kilden bruker

stemmer
0

Jeg hadde et resultat objekt som faller gjennom en serie av validere hulroms metoder som en metode parameter. Hver av disse validere hulroms metodene vil mutere resultatet parameter objekt for å legge resultatet av valideringen.

Men dette er umulig å teste fordi nå kan jeg ikke spire tomrommet metode for å returnere en spire verdi for validering i resultatobjektet.

Så, fra et test perspektiv viser det seg at man bør favorisere returnerer et objekt i stedet for å mutere en metode parameter.

Svarte 17/12/2009 kl. 20:11
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more