Implizite java.lang.Integer-Typwandlungen in Java (Implizite java.lang.Integer-Typwandlungen in Java), Lektion, Seite 723304
https://www.purl.org/stefan_ram/pub/implizite_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Java-Kurs

Implizite java.lang.Integer-Verpackung in Java 

Die implizite Verpackung

Die Operation »valueOf« wird auch bei der impliziten Verpackung  verwendet: Wenn ein elementarer Wert an einer Stelle verwendet wird, an der ein Objekt erwartet wird, so wird der elementare Wert in bestimmten Fällen (bei der Zuweisung und bei Argumentwerten) in ein Objekt verpackt, ohne  daß dies ausdrücklich verlangt werden muß.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final int w = 2;
final java.lang.Integer o = w; /* implizite Verpackung */
final java.lang.Integer v = 3; /* implizite Verpackung */
java.lang.System.out.println( w );
java.lang.System.out.println( o );
java.lang.System.out.println( v ); }}
Protokoll
2
2
3

Das voranstehende Programm mit impliziter Verpackung entspricht dem folgenden Programm mit expliziter  Verpackng.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final int w = 2;
final java.lang.Integer o = java.lang.Integer.valueOf( w );
final java.lang.Integer v = java.lang.Integer.valueOf( 3 );
java.lang.System.out.println( w );
java.lang.System.out.println( o );
java.lang.System.out.println( v ); }}
Protokoll
2
2
3

In dem folgenden Programm wird der int-Wert »2« an einer Stelle angegeben, an der eine Objekt-Referenz erwartet wird. Auch hier erfolgt wieder eine implizite Verpackung.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.lang.Integer p = java.lang.Integer.valueOf( 4 );
java.lang.System.out.println( p.equals( 2 )); }}
transcript
false

Bei der impliziten Verpackung erkennt der Übersetzer die Notwendigkeit zur Verpackung und erzeugt selbständig die notwendige Exemplarerzeugung. Dadurch entspricht der obige Quelltext dem folgenden, in dem die Operation »java.lang.Integer.valueOf(int)« verwendet wird, um ein java.lang.Integer-Exemplar mit dem Wert »2« zu erhalten.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.lang.Integer p = new java.lang.Integer( 4 );
java.lang.System.out.println( p.equals( java.lang.Integer.valueOf( 2 ))); }}
transcript
false

Die implizite Verpackung bewirkt also im allgemeinen keine schnellere Programmausführung als eine explizite Verpackung, sie kann jedoch das Schreiben des Quelltextes erleichtern. Außerdem ermöglicht sie es dem verwendeten Übersetzer die jeweils beste Möglichkeit zur Verpackung zu wählen: So könnte eine zukünftige Übersetzer-Version dort auch eine heute noch nicht bekannte Operation verwenden, die nicht eingesetzt werden könnte, wenn der Programmierer eine Art der Verpackung explizit verschreibt. Wenn die Art der Verpackung (z.B. mit der Exemplarerzeugung »new java.lang.Integer(int)« oder der Operation »java.lang.Integer.valueOf(int)«) egal ist, dann sollte der Programmierer also die implizite Verpackung verwenden und die Wahl der besten Möglichkeit somit dem jeweiligen Übersetzer ermöglichen.

Die implizite Verpackung tritt jedoch nicht in allen Fällen ein. In dem folgenden Beispiel könnte die Zahl »4« automatisch verpackt werden, was aber in Java nicht geschieht.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( 4.equals( 2 )); }}
transcript
Main.java:3: error: malformed floating point literal
{ java.lang.System.out.println( 4.equals( 2 )); }}
^

In manchen anderen Programmiersprachen sind auch solche Schreibweisen erlaubt.

Die implizite Verpackung soll in Java  einige Umständlichkeiten erleichtern, die dadurch entstehen, daß Java  nicht rein objektorientiert ist. In einer reinen objektorientierten Programmiersprache gibt es gar keine  elementaren Werte, so daß dort die Notwendigkeit zu einer impliziten Verpackung entfällt.

Implizite Entpackung

Falls eine Referenz auf ein Objekt der Klasse »java.lang.Integer« an einer Stelle gefunden wird, an der ein elementarer Wert erwartet wird, so wird dieser in vielen Fällen implizit entpackt.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.lang.Integer o = new java.lang.Integer( 4 );
final int i = o; /* implizite Entpackung */
java.lang.System.out.println( i ); }}
transcript
4

Das voranstehende Programm mit impliziter Entpackung entspricht dem folgenden Programm mit expliziter  Entpackung.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.lang.Integer o = new java.lang.Integer( 4 );
final int i = o.intValue();
java.lang.System.out.println( i ); }}
transcript
4

Implizite Entpackung bei Operatoren

Auch wenn ein java.lang.Integer-Objekt zusammen mit einem Operator verwendet wird, der mit einem int-Operanden verwendet werden kann, erfolgt eine implizite Entpackung, außer, wenn der Operator auch mit Objekten verwendet werden kann, wie etwa beim Operator »==«. Deswegen werden beim Vergleich mit »<« die Zahlenwerte, aber beim Vergleich mit »==« die Objektreferenzen verglichen. Um das auszudrücken, was man bei Operanden vom Typ »int« mit »<« schreiben würde, kann man also auch bei Operanden vom Typ »java.lang.Integer« den Operator »<« verwenden. Will man aber das auszudrücken, was man bei Operanden vom Typ »int« mit »==« schreiben würde, muß man bei Operanden vom Typ »java.lang.Integer« den Methodennamen »equals« verwenden.

Main.java
public final class Main
{ public static void main( final java.lang.String[] args )
{ final java.lang.Integer o = new java.lang.Integer( 3 );
final java.lang.Integer v = new java.lang.Integer( 3 );
java.lang.System.out.println( -o ); /* -3 */
java.lang.System.out.println( o + v ); /* 6 */
java.lang.System.out.println( o < v ); /* false */
java.lang.System.out.println( o == v ); /* false */
java.lang.System.out.println( o.equals( v )); /* true */ }}
transcript
-3
6
false
false
true

Implizite Verpackung bei Zuweisungen

Durch die implizite Verpackung ist es möglich, einer Variablen eines geeigneten Obertyps sowohl Referenzen als auch elementare Werte zuweisen zu können.

Unsere bisherigen Regeln über Untertypen müssen erweitert werden, denn »2« hat keinen Untertyp von »java.lang.Object«, kann aber trotzdem einer Variablen dieses Typs zugewiesen werden.

Main.java

public final class Main
{

public static void main( final java.lang.String[] args )
{ java.lang.Object v;
v = new java.lang.Object(); java.lang.System.out.println( v );
v = "abc"; java.lang.System.out.println( v );
v = true; java.lang.System.out.println( v );
v = 2; java.lang.System.out.println( v );
v = 2.3; java.lang.System.out.println( v ); }}

transcript
java.lang.Object@15db9742
abc
true
2
2.3

Implizite Verpackung bei Parameter

Durch die implizite Verpackung ist es möglich, eine einzige Methode sowohl mit Referenzen als auch mit einem elementaren Werten aufrufen zu können.

Unsere bisherigen Regeln über Untertypen müssen erweitert werden, denn »2« hat keinen Untertyp von »java.lang.Object«, kann aber trotzdem für einen Parameter dieses Typs als Argument verwendet werden.

Main.java

public final class Main
{

public static void println( final java.lang.Object value )
{ java.lang.System.out.println( value.getClass() + ": " + value ); }

public static void main( final java.lang.String[] args )
{ println( new java.lang.Object() );
println( "abc" );
println( true );
println( 2 );
println( 2.3 ); }}

transcript
class java.lang.Object: java.lang.Object@15db9742
class java.lang.String: abc
class java.lang.Boolean: true
class java.lang.Integer: 2
class java.lang.Double: 2.3

Übungsfragen

?   Deklarationsfehler

Welche Zeilen der folgenden Quelldatei enthalten Fehler, und welche Fehler wurden gemacht?

Main.java

public final class Main
{ public static void main( final java.lang.String[] args )
{

final java.lang.Integer i = new java.lang.Integer;
final java.lang.Integer j = 0;
final int k = 0;
final java.lang.Integer l = new.java.lang.Integer( 2 );
final java.lang.Integer m = java.lang.Integer( 2 );

}}

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723304 stefan_ram:723304 Implizite java.lang.Integer-Typwandlungen in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723304, slrprddef723304, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/implizite_java