Generic - Autoboxing

Javt

Aktives Mitglied
Hi,

Normalerweise sind doch bei Generics als Parameter nur Klassen und keine primitiven Datentypen zugelassen. Wieso ist dann folgendes möglich?:
Java:
    public static <V> V first(V wert1, V wert2) {
		return wert1;
	}
	
	public static void main(String[] args) {
		first(1, 2);
	}

Macht der Compiler hier ein Autoboxing nach Integer oder wie ist das zu verstehen?
 
Passiert doch genauso, wenn du eine ArrayList<Integer> befüllst: add(5);
Da wird auch nur Autoboxing betrieben ^^
 
Also legt der Compiler automatisch den Typ von "V" als "Integer" fest und macht dann für die zwei primitiven Datentypen ein Autoboxing oder?
 
"Comparable" ist doch normalerweise ein "Interface". Wieso kann man es bei Generics einfach erweitern "extend"? (es heißt normalerweise "implements"):
Java:
public static <T extends Comparable<T>> T max( T m, T n )
{
  return m.compareTo( n ) > 0 ? m : n;
}

lg
 
Das
Code:
extends
bei den Generics hat gar nichts mit erweitern oder implementieren zutun. Das nennt sich bounded wildcards, bzw. bounded type parameters.
 
Das ist in der Tat inkonsequent. Allerdings kannst du mehrere Bounds für eine Typvariable haben, und [c]<T extends Number implements Serializable>[/c] fanden dann wahrscheinlich selbst die Java-Gurus zu heavy, und haben es bei [c]<T extends Number & Serializable>[/c] belassen.

Ich persönlich wäre sehr dafür, sich generell auf ein einziges Schlüsselwort bei der Vererbung zu einigen. Es passiert eben doch hin und wider, dass man aus einem Interface eine abstrakte Klasse macht (oder umgekehrt) und dann überall das [c]implements[/c] durch [c]extends[/c] ersetzen muss.
 
Zuletzt bearbeitet:
Das ist in der Tat inkonsequent. Allerdings kannst du mehrere Bounds für eine Typvariable haben, und [c]<T extends Number implements Serializable>[/c] fanden dann wahrscheinlich selbst die Java-Gurus zu heavy, und haben es bei [c]<T extends Number & Serializable>[/c] belassen.
Wieso ist das inkonsequent? Dass bei Generics die Unterscheidung zwischen Klassen und Interfaces irrelevant ist ist doch eine IMHO gute Entscheidung gewesen. Oder willst du in der Praxis T auf Klassen oder Interfaces einschränken, und die Generics-Geschichte noch weiter aufblähen?
 
Hast du meinen Post überhaupt gelesen? Ich habe ein Beispiel gebracht, wo eine Unterscheidung zwischen [c]extends[/c] und [c]implements[/c] bei Generics genau zu dieser Aufblähung geführt hätte.

Trotzdem ist es inkonsistent hinsichtlich der "normalen" Verwendung, wobei ich dafür plädieren würde, auch dort nur ein Schlüsselwort (etwa [c]extends[/c]) für alles zu verwenden - bei genauerem Hinsehen ist der Unterschied dort auch ziemlich irrelevant.
 
Naja ich würd das dahingehend sehen das der generische Typ ja erstmal unbekannt ist also Klasse oder Interface sein kann. Und ein Interface erbt ja auch über extends. Deswegen find ich macht das schon sind bei generics.

Allerdings bei implementierungen find ichs eigentlich besser so, weil dadurch auch nochmal besser rüberkommt, dass man nur von einer Klasse direkt Vererben kann aber mehrere implementieren.
 
@Clayn: Ein Interface wird nicht erweitert ("extends"), es wird implementiert ("implements")

Finde es gut, dass bei Generics nicht unterschieden wird. Dann muss man sich allerdings zwangsläufig auf einen Begriff einigen oder man führt ein ganz neues Schlüsselwort ein, was auch wieder aufgebläht wirken würde
 
Zuletzt bearbeitet von einem Moderator:
Das ein Interface implementiert ist mir klar. Aber ich meine ein Interface was von einem Interface erbt. Das wird wiederum mit extends gemacht. Z.B.:
Java:
public interface SomeInterfaceA {
}

public interface SomeInterfaceB extends SomeInterfaceA{
}

jetzt klarer geworden was ich meine?
 
Jep, das ist auch schon wieder so ein spezieller Fall, der zu Missverständnissen führen könnte...
 
Man muss den C#-Jungs neidlos zugestehen, dass das dortige ":" um einiges besser als das aufgeblähte extends/implements-Geraffel von Java ist. Wer weiß, welcher Overengineering-Teufel Sun damals geritten hatte.
 
Naja was heißt spezieller Fall. Das Interface erweitert ja das bestehende also finde ich die Namensgebung schon passend.

Und von wegen für alles extends was ist wenn man sowas hat?

Java:
public class Foo extends A,B,C,D 
{

}

Wenn das jemand sieht weißt man gar nicht was da nun ne klasse ist oder ein Interface oder sonstwas.
 
Und von wegen für alles extends was ist wenn man sowas hat?

Java:
public class Foo extends A,B,C,D 
{

}

Wenn das jemand sieht weißt man gar nicht was da nun ne klasse ist oder ein Interface oder sonstwas.
Klar, wenn man derart unsinnige Klassennamen nimmt kann man da natürlich wunderbar ein Problem hinkonstruieren, wo gar keins ist. Bei sprechenden Namen hingegen ist sehr wohl klar, was Basisklasse und was zusätzliche Fähigkeiten sind. Außerdem halte ich das ewige Interface vs. Klasse eh für Käse. Man sollte gegen Interfaces programmieren und es sollte so einfach wie möglich sein Interfaces gegen Klassen gegen Traits / Mixins oder was weiß ich noch zu tauschen OHNE dafür jedesmal implements gegen extends zu tauschen, und ähnliche Späßchen zu veranstalten.

Wenn ich sowas hier habe:
Java:
class Person : Creature, HasName, CanSpeak {
    ....
}
dann kommuniziert das klar und deutlich was eine Person für mich ist. HasName und CanSpeak können interfaces sein. Es könnten aber auch Mixins sein. Was es genau ist wird durch die einheitliche Notation schön entkoppelt.
 
Ich finde es immer lustig wie Ihr Euch über so kleine Syntaxdinge streiten könnt 🙂 Wer erst einmal eine Sprache unter den Fingern hat die einen zum Einrücken zwingt (Codeblockdefinition) der weint bei sowas nicht mehr *g* *duck*
 

Neue Themen


Zurück
Oben