Output parameter

Odeslat odpověď

Smajlíci
:D :) :( :o :shock: :? 8) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen:

BBCode je zapnutý
[img] je zapnutý
[flash] je vypnutý
[url] je zapnuté
Smajlíci jsou zapnutí

Přehled tématu
   

Rozšířit náhled Přehled tématu: Output parameter

Re: Output parameter

od Betlista » 2. 2. 2010 12:43

t2 píše:Ahoj

pri b = false nevznika novy objekt.
To nie je pravda, stačí si skúsiť:

Kód: Vybrat vše

public class BooleanOutput {

	static void skuska( Boolean b ) {
		Boolean old = b;
		b = true;
		System.out.println( old == b ); // false, takže nejsou stejné !!!
	}

	public static void main(String[] args) {
		Boolean b = false;
		System.out.println( b );
		skuska( b );
		System.out.println( b );
	}

}
Dôvod je jednoduchý v Jave 1.5 je

Kód: Vybrat vše

Boolean b = false;
iba náhražkou

Kód: Vybrat vše

Boolean b = new Boolean( false );
v jave 1.4 to bolo potreba písať, v 1.5 to uľahčili ale pre ľudí, ktorí si Javu 1.4 nezažili je to mätúce...
t2 píše:Problem je, ze ty mas dve boolean premenne, jedna je v metode main a druha metode skuska.
Toto tiež nie je pravda, veď si uvedom, že keby toto bola pravda, tak nefunguje ani ten Tvoj príklad. Objekty sa predávajú odkazom a primitívne typy hodnotou (predstav si, že by si do metódy predával obrovský objekt a on by sa celý najprv zduplikoval, to je dôvod prečo to nefunguje a to nehovorím o tom, že ani nie je jasné ako urobiť kópiu objektu), správne je to, čo písal kolega vyššie - wrapper typy sú immutable, teda nemeniteľné.

Okrem spôsobu s ErrorState existuje spôsob bez vytvárania novej triedy:

Kód: Vybrat vše

public class BooleanOutput {

	static void skuska2( Boolean[] b ) {
		b[0] = true;
	}

	public static void main(String[] args) {
		System.out.println( b );
		Boolean[] ba = new Boolean[] {b};
		skuska2( ba );
		System.out.println( ba[0] );
	}

}
ale ani tento spôsob by som nedoporučoval, z hľadiska OOP a dizajnu je správne, aby si urobil tzv. krabičku (Crate), ktorá obalí obe návratové hodnoty:

Kód: Vybrat vše

public class BooleanOutputCrate {

	static Crate skuska() {
		return new Crate( 10, false );
	}

	public static void main(String[] args) {
		skuska();
	}

	static class Crate {
		int i;
		boolean b;
		Crate( int i, boolean b ) {
			this.i = i;
			this.b = b;
		}
	}
}
Pretože output parametre sú nečitateľné pre niekoho, kto daný kód nepozná.

Re: Output parameter

od t2 » 17. 5. 2009 20:53

Ahoj

pri b = false nevznika novy objekt. Problem je, ze ty mas dve boolean premenne, jedna je v metode main a druha metode skuska. Pri zavolani skuska sa referencia odovzda hodnotou. Ale to ze zmenis kam referencia v metode skuska ukazuje (na false) nezmeni to, kam ukazuje referencia v metode main (na true). Pri zachovani semantiky tvojho programu to ide spravit tak, ze si tu boolean hodnotu zabalis do svojej triedy. Takto

Kód: Vybrat vše

public class A {
    
    static class ErrorState {
	boolean flag;
    }
    
    private static void skuska(ErrorState state) {
	state.flag = false;
	System.out.println(state.flag);
    }
    
    public static void main(String[] args) {       
        ErrorState errorState = new ErrorState();
        errorState.flag = true;
        System.out.println(errorState.flag);
        skuska(errorState);
        System.out.println(errorState.flag);      
     } 
    
}
Rozdiel je v tom, ze v celom programe sa pracuje len s jednou instanciou ErrorState, na ktoru ukazuju dve nezavisle referencie.

Inak ako bolo spomenute, krajsim a lepsim sposobom ako signalizovat chybu je vyhodit vynimku alebo pouzit navratovu hodnotu.

Re: Output parameter

od Lado » 17. 5. 2009 20:46

Osiris píše:Ale samozřejmě jde například vracet příslušná hodnota Boolean místo void.
Ano, to ide, ale toto je len priklad. V aplikacii mam uz navratovu hodnotu.
Tak ci tak, vdaka za vysvetlenie. Nenapadlo ma, ze pri b = false vznika novy objekt a ten sa tam priraduje. Som si myslel, ze sa len nastavi jeho hodnota ( pretazeny operator= ). Ale to su zle zvyky z C/C++/C# :)

Re: Output parameter

od Osiris » 17. 5. 2009 20:43

Ale samozřejmě jde například vracet příslušná hodnota Boolean místo void.

Re: Output parameter

od Osiris » 17. 5. 2009 20:42

Obávám se, že jde o immutable třídu, takže nijak.

Re: Output parameter

od Lado » 17. 5. 2009 20:37

Ok, dava to nejaky zmysel - otazka je, ako to upravit, aby sa to chovalo tak, ako ja chcem?

Re: Output parameter

od Osiris » 17. 5. 2009 20:29

Vždyť se to chová korektně! Uvědom si, že

Kód: Vybrat vše

   private static void skuska(Boolean b) {
      b = false;
      System.out.println(b);
   }
Ti do b dosadí novou referenci na jiný objekt. Jenže ty tu referenci předáváš HODNOTOU!

Output parameter

od Lado » 17. 5. 2009 20:15

Ahoj,
mam taky mensi problem s output parametrami. Chcem signalizovat error z nejakej metody ( cize zmenit boolean hodnotu ). Je jasne, ze pre boolean to nejde, lebo sa predava hodnotou. Ale pre Boolean by to malo ist - vid ukazka kodu

Kód: Vybrat vše

	public static void main(String[] args) {        
			Boolean a = Boolean.valueOf(true);
			System.out.println(a);
			skuska(a);
			System.out.println(a);		
		}
	
	private static void skuska(Boolean b) {
		b = false;
		System.out.println(b);
	}
Mozete hadat, coto vypise - true, false, true (!!!).
Vie mi to niekto vysvetlit? Vsade na nete pisu, ze by to malo dat true, false, false, ale akosi nedava.
Pre istotu
The Boolean class wraps a value of the primitive type boolean in an object. An object of type Boolean contains a single field whose type is boolean.

Nahoru