You are not logged in.

  • Login

1

Saturday, July 23rd 2011, 9:20pm

Default Werte für Parameter

Hallo,

Ich steh vor eine Frage auf die ich keine Lösung weiß. Ich will das auch eigentlich gar nicht nutzen aber vllt. wäre es ganz gut zu wissen was man da machen könnte ;):

Quoted

In Java gibt es anders als in C++ keine Defaultwerte für Parameter. Wie wüurden
Sie in Java stattdessen ausdrüucken, dass standardmäaßig bestimmte Parameter mit
einen Defaultwert belegt sind?


Was gibts denn da für Möglichkeiten? Ich dachte zuerst im Konstruktor direkt Werte zuweisen aber dann würde man ja welche vllt. überschreiben - oder auf null überprüfen und dem entsprechend was setzen, finde ich aber ehrlich gesagt ziemlich komsich Oo.

2

Saturday, July 23rd 2011, 11:27pm

Man könnte die Methoden einfach überladen mit verschiedener Parameteranzahl. Die überladenen Methoden rufen dann einfach die normale Methode auf.
(So macht es meines Wissens auch die JavaAPI)

Java Quellcode

1
2
3
4
5
6
void foo(String param){
  //...
}
void foo(){
  foo("default");
}


Wobei ich glaube, dass in einem der nächsten Javaupdated sowieso irgendetwas derartiges in der Sprache integriert sein wird.

m

Unregistered

3

Sunday, July 24th 2011, 12:55am

Die genannte Überladung ist für Methoden mit wenigen Parameter die einfachste Lösung für dieses Problem.

Es lässt sich allerdings auch mit nur einer Methodendeklaration lösen:

1. Primitiv: Einfacher Null-Check im Methodenkörper:

Java Quellcode

1
2
3
4
5
6
7
void bla(String name) {
	if (name == null) {
		doSomething("Hans");
	} else {
		doSomething(name);
	}
}

2. Fortgeschritten: Du annotierst die Parameter und wertest diese aus:

Java Quellcode

1
2
3
4
5
6
7
8
void bla(@Default("Hans") String name) {
	if (name == null) {
		String defaultValue = ... // Annotation auswerten
		doSomething(defaultValue);
	} else {
		doSomething(name);
	}
}

Die letzte Möglichkeit hat zwar einen höheren Initialaufwand, bringt aber den nicht zu unterschätzenden Vorteil, dass die Defaultwerte aus der Methodensignatur ersichtlich sind. Was du bei Überladung oder Überprüfungen im Methodenkörper eben nicht hast.

4

Sunday, July 24th 2011, 11:01am

Ah, das ist ja schonmal gut! Auf Methoden überladen hätte ich eigentlich kommen müssen :pinch: .

Was mir neu ist ist dieses "@Default("Hans") - ist sowas echt im Parameterbereich erlaubt Oo? Diese Annotation ist doch sowas wie @Override und so, richtig?

5

Sunday, July 24th 2011, 11:21am

Danke m für diesen Beitrag! Default Paramter Annotations waren mir gänzlich neu.
Aber diese gehören nicht zum Standardumfang, oder? Dazu muss ich die JavaDude Libs in meinen Buildpath einhängen: http://code.google.com/p/javadude/wiki/Annotations

Quoted

If you're creating a plugin, you can add a dependency to the com.javadude.annotation plugin. Otherwise:

Download javadude-annotation_2.1.6.jar and import it into your project. (Alternatively you can place it in another project, export it, and add the other project as a dependency)
Right-click on the jar and choose Build Path->Add to Build Path. (This gives you access to the annotation definitions so you can use them in your code.)
Open your project properties (Select the project and press Alt-Enter)
Go to Java Compiler->Annotation Processing
Check Enable project specific settings
Uncheck Enable processing in editor (not really necessary but can improve performance slightly)
The plugin will automatically process the @Bean and @ExtractInterface annotations.

m

Unregistered

6

Sunday, July 24th 2011, 5:39pm

Die JavaDude Libs gehen allerdings einen gänzlich anderen Weg. Siehe das Beispiel auf deren Seite: http://code.google.com/p/javadude/wiki/A…ropertyExample1
Im Prinzip wird da alles bereits vor dem Kompilieren automatisch zu fertigen Klassen zusammengebaut. Die Annotationen dienen quasi als Bauplan. Am Ende kommen also ganz normale Klassen raus, die kaum noch Spuren enthalten, aus was sie eigentlich entstanden. Ich hingegen werte die Infos erst zur Laufzeit aus. Solche Sachen zur Laufzeit zu machen ist zwar schwieriger zu handhaben, wird aber insgesamt der Objektorientierung besser gerecht, also dem Fokus auf der Dynamik von Objekten und ihrem Verhalten zur Laufzeit, statt auf dem statischen Klassenmodell mit seinen starren Beziehungen.

AFAIK ist nichts derartiges in der Standard-API von Java. Die Annotationen kann man sich aber relativ leicht selbst bauen:

Default.java

Java Quellcode

1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Default {
	String value();
}


Die Auswertung von Annotationen zur Laufzeit ist mit ein paar Umwegen verbunden. Man muss sich quasi von der Klasse, über die Methode, den ersten Parameter bis zur ersten dortigen Annotation hangeln. Wenn man es aber einmal verstanden hat, ist das Ganze absolut logisch. Außerdem kann man solche Sachen in Helper-Klassen auslagern, was die Auswertung der Annotation zum EInzeiler macht. Aber zum Verständnis hier der lange Weg:

Java Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Hello {
 
	public void sayHi(@Default("Horst") String name) {
		if (name == null) {
			try {
				Method thisMethod = this.getClass().getMethod("sayHi", String.class);
				Annotation[][] annotations = thisMethod.getParameterAnnotations();
				Default annotation = (Default) annotations[0][0];
				System.out.println("Hallo " + annotation.value() + "!");
			} catch (Exception e) {
			}
		} else {
			System.out.println("Hallo " + name + "!");
		}
	}
 
}


Benutzung ganz normal:

Java Quellcode

1
2
3
4
5
public static void main(String[] args) {
		Hello h = new Hello();
		h.sayHi("Kevin");
		h.sayHi(null);
	}


Source code

1
2
Hallo Kevin!
Hallo Horst!

7

Sunday, July 24th 2011, 5:55pm

Nett! Finde ich so absolut sinnvoll. Magst du eine Wiki Seite draus machen? http://www.easy-coding.de/wiki/java/
Ansonsten schreib ich mir das als Task.
Lg

m

Unregistered

8

Monday, July 25th 2011, 11:30pm

Sorry, die nächsten Wochen sieht es bei mir zeitlich ziemlich knapp aus (wg. Job und Uni). Das Thema ist aber nicht aus der Welt.

Social bookmarks