Welchen wert hat i? | Java?

4 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

int und Integer haben eine besondere Beziehung zueinander in Java.

int ist der primitive Datentyp und erlaubt daher ein paar syntaktische Besonderheiten, etwa dass er einfach als int i = 0 deklariert und initialisiert werden kann und man sich den new-Overhead einer Klasseninstanziierung spart (bzw. genauer liegt das daran, dass 0 als primitiver int bereits immer existiert und damit nicht mehr extra instanziiert werden muss).

Integer ist der dazugehörige Wrapper-Typ. d.h. eine reale Klasse mit Konstruktor und Methoden. Er kapselt im Grunde genommen den primitiven Datentyp in ein OOP-verträgliches Objekt. Wrapper-Typen benötigt man zum Beispiel für Umwandlungen (Integer.valueOf(...) erlaubt zum Beispiel die Typumwandlung von String nach Integer) und für Listen (Listentypen dürfen keine primitiven Typen sein).

Trotzdem ist eine Umwandlung von int nach Integer und andersherum oft notwendig (denn beide sind ja abstrakt verschiedene Repräsentationen des selben Objekts). Deshalb ist int (bzw. alle primitiven Datentypen) eines der wenigen Beispiele, mit dem eine implizite Typumwandlung möglich ist. Normalerweise ist eine Zuweisung

A a = b;

nur dann erlaubt, wenn b vom Typ A (oder ein Kind davon) ist. (Ich kann ja nicht

Katze k = new Katze();
Hund h = katze;

schreiben.)

Allerdings sind int und Integer weder dieselben Typen, noch ist eins ein Kind des anderen.

"Explizite implizite" Typumwandlung (d.h. dass man in der Klasse B selbst (= explizit) festlegt, wie eine Instanz wie b z.B. in einem Ausdruck wie oben ohne weiteren Code (= implizit) als A interpretiert werden kann) wie sie beispielsweise in C++ möglich ist, gibt es in Java nicht. Bei Typen, die zu Java selbst gehören, weiß der Compiler aber ausdrücklich, wie er sie umwandeln soll (das ist eine Besonderheit und nur einzelnen internen Java-Klassen vorbehalten!). Daher ist eine Initialisierung

Integer i = 0;

möglich, obwohl links und rechts zunächst komplett verschiedene Typen stehen. Der Compiler wendet den primitiven int rechts implizit (d.h. automatisch) in eine Integer-Instanz um. Das heißt, obiges ist äquivalent zu

Integer i = new Integer(0);

nur muss es nicht so explizit geschrieben werden. Genauso funktioniert auch die andere Richtung, d.h. der Compiler castet eine Integer-Instanz automatisch zu einem int, wenn es notwendig ist. In deinem Code passiert nun folgendes:

  1. Deklariere i als Integer.
  2. Erzeuge eine neue Integer-Instanz, die den int 0 enthält und weise diese i zu.
  3. Wandle (den int) 0 zu int um (redundant) und weise dies i zu. Hier findet die implizite Typumwandlung statt. Im Wesentlichen passiert aber nichts, weil i bereits vor Zeile 6 den Wert Integer(0) hatte.

i ist also in Zeile 6 der Integer, der 0 enthält.

Im Übrigen nimmt der Compiler eine unmögliche Umwandlung in der Regel nicht einfach stillschweigend hin und setzt stattdessen null. Üblicherweise wirft er in so einem Fall eine ClassCastException und verursacht einen Programmabbruch.

Woher ich das weiß:Berufserfahrung – Software-Entwicklung

xam193 
Beitragsersteller
 28.05.2021, 11:35

Vielen Dank für die ausführliche Antwort!

1

Ich hab nichts mit Java zu tun, aber in C++ bspw. gibt es "implicit conversions", was heißt, dass wenn alle Parameter für die Erstellung eines Objekts vorhanden sind, dieses Objekt im Zweifel auch ohne explizite Angabe des Konstruktors erstellt wird. "new Integer(0)" läuft dann also im Hintergrund ab, wenn du nur den Parameter "0" angibst.

Ich hätte jetzt gesagt es wäre null, weil man eben dieses Objekt i nicht in einen int umwandeln kann.

Hier passieren zwei "Umwandlungen", wobei eine unnötig ist. Das Literal 0 ist bereits vom Typ int, also ist das (int) davor redundant und hat keinen Effekt. Man könnte es weglassen, das Resultat wäre genau gleich.

Darüber hinaus passiert aber bei der Zuweisung eine Umwandlung, die man Autoboxing nennt. Dabei wird der primitive Typ (hier: int) automatisch in die jeweilige Wrapperklasse (hier: Integer) konvertiert. Der Compiler spart dir also etwas Tipparbeit.

https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

https://docs.oracle.com/javase/specs/jls/se11/html/jls-5.html#jls-5.1.7


xam193 
Beitragsersteller
 28.05.2021, 11:35

Danke!

0

In diesem Fall ist "i = 0" und "i = (int)0" völlig identisch. In beiden Fällen wird der Integer-Wert 0 zugewiesen. "(int)" ist in der Tat eine Typumwandlung, da hier aber nichts umzuwandeln ist, kann man "(int)" auch weglassen.

Woher ich das weiß:Studium / Ausbildung – Datenverarbeitungs-Kfm, Hobby- und Profi-Programmierer