Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Neues in Java 7
2 Threads und nebenläufige Programmierung
3 Datenstrukturen und Algorithmen
4 Raum und Zeit
5 Dateien, Verzeichnisse und Dateizugriffe
6 Datenströme
7 Die eXtensible Markup Language (XML)
8 Dateiformate
9 Grafische Oberflächen mit Swing
10 Grafikprogrammierung
11 Netzwerkprogrammierung
12 Verteilte Programmierung mit RMI
13 RESTful und SOAP Web-Services
14 JavaServer Pages und Servlets
15 Applets
16 Datenbankmanagement mit JDBC
17 Technologien für die Infrastruktur
18 Reflection und Annotationen
19 Dynamische Übersetzung und Skriptsprachen
20 Logging und Monitoring
21 Java Native Interface (JNI)
22 Sicherheitskonzepte
23 Dienstprogramme für die Java-Umgebung
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
Java 7 - Mehr als eine Insel von Christian Ullenboom
Das Handbuch zu den Java SE-Bibliotheken
Buch: Java 7 - Mehr als eine Insel

Java 7 - Mehr als eine Insel
Rheinwerk Computing
1433 S., 2012, geb.
49,90 Euro, ISBN 978-3-8362-1507-7
Pfeil 18 Reflection und Annotationen
Pfeil 18.1 Metadaten
Pfeil 18.1.1 Metadaten durch JavaDoc-Tags
Pfeil 18.2 Metadaten der Klassen mit dem Class-Objekt
Pfeil 18.2.1 An ein Class-Objekt kommen
Pfeil 18.2.2 Was das Class-Objekt beschreibt *
Pfeil 18.2.3 Der Name der Klasse
Pfeil 18.2.4 instanceof mit Class-Objekten *
Pfeil 18.2.5 Oberklassen finden *
Pfeil 18.2.6 Implementierte Interfaces einer Klasse oder eines Interfaces *
Pfeil 18.2.7 Modifizierer und die Klasse Modifier *
Pfeil 18.2.8 Die Arbeit auf dem Feld *
Pfeil 18.3 Attribute, Methoden und Konstruktoren
Pfeil 18.3.1 Reflections – Gespür für die Attribute einer Klasse
Pfeil 18.3.2 Methoden einer Klasse erfragen
Pfeil 18.3.3 Properties einer Bean erfragen
Pfeil 18.3.4 Konstruktoren einer Klasse
Pfeil 18.3.5 Annotationen
Pfeil 18.4 Objekte erzeugen und manipulieren
Pfeil 18.4.1 Objekte erzeugen
Pfeil 18.4.2 Die Belegung der Variablen erfragen
Pfeil 18.4.3 Eine generische eigene toString()-Methode *
Pfeil 18.4.4 Variablen setzen
Pfeil 18.4.5 Bean-Zustände kopieren *
Pfeil 18.4.6 Private Attribute ändern
Pfeil 18.4.7 Methoden aufrufen
Pfeil 18.4.8 Statische Methoden aufrufen
Pfeil 18.4.9 Dynamische Methodenaufrufe bei festen Methoden beschleunigen *
Pfeil 18.5 Eigene Annotationstypen *
Pfeil 18.5.1 Annotationen zum Laden von Ressourcen
Pfeil 18.5.2 Neue Annotationen deklarieren
Pfeil 18.5.3 Annotationen mit genau einem Attribut
Pfeil 18.5.4 Element-Werte-Paare (Attribute) hinzufügen
Pfeil 18.5.5 Annotationsattribute vom Typ einer Aufzählung
Pfeil 18.5.6 Felder von Annotationsattributen
Pfeil 18.5.7 Vorbelegte Attribute
Pfeil 18.5.8 Annotieren von Annotationstypen
Pfeil 18.5.9 Deklarationen für unsere Ressourcen-Annotationen
Pfeil 18.5.10 Annotierte Elemente auslesen
Pfeil 18.5.11 Auf die Annotationsattribute zugreifen
Pfeil 18.5.12 Komplettbeispiel zum Initialisieren von Ressourcen
Pfeil 18.5.13 Mögliche Nachteile von Annotationen
Pfeil 18.6 Zum Weiterlesen

Rheinwerk Computing - Zum Seitenanfang

18.3 Attribute, Methoden und KonstruktorenZur nächsten Überschrift

Ein Class-Objekt bietet nicht nur Zugriff auf Oberklassen, Sichtbarkeiten, Modifizierer und Schnittstellen, sondern natürlich auch auf die Variablen, Methoden und Konstruktoren einer Klasse oder Schnittstelle. Daher kooperiert Class mit fünf weiteren Typen:

  • Constructor: Steht für die Konstruktoren einer Klasse. So gibt zum Beispiel getConstructors() ein Feld von Konstruktoren zurück.
  • Field: Ermöglicht den Zugriff auf die Objekt- und Klassenvariablen, um später Belegungen lesen und Werte verändern zu können.
  • Method: Steht für die Methoden einer Klasse beziehungsweise Operationen der Schnittstellen. So liefert getDeclaredMethods() die Methoden, die dann später mit invoke() aufgerufen werden können.
  • Annotation: Repräsentiert die Annotationen, die an der Klasse/Schnittstelle festgemacht sind. So liefert zum Beispiel die Class-Methode getAnnotations() die festgemachten Annotationen.
  • Package: getPackage() liefert ein Package-Objekt für die Klasse, die eine Versionsnummer beinhaltet, wenn diese im Manifest gesetzt wurde.

Weiterhin gibt es folgende allgemeine Implementierungsbeziehungen:

  • Die Klassen Class, Method, Field und Constructor implementieren eine Schnittstelle Member, um etwa den Namen, die Modifizierer oder die deklarierende Klasse zu erfragen.
  • Die Klassen Class, Constructor und Method implementieren die Schnittstelle GenericDeclaration, da sie generische Typvariablen deklarieren können.
  • Die Klassen Constructor, Field und Method implementieren AccessibleObject, um die Sichtbarkeit auszuschalten.
  • Class, Constructor, Field, Method und Package implementieren AnnotatedElement, weil sie Annotationen tragen können.

Reflections-Exceptions und ReflectiveOperationException

Ist etwas so dynamisch wie Reflection, kann eine Menge schiefgehen. Nahezu alle Methoden zum Zugriff auf Laufzeitinformationen lösen daher die eine oder andere Ausnahme aus. An dieser Stelle sollen die zentralen Ausnahmen kurz vorgestellt werden. Alle stammen aus dem Paket java.lang:

  • NoSuchFieldException und NoSuchMethodException: Das Attribut oder die Methode wird erfragt, aber existiert nicht.
  • ClassNotFoundException: Der Klassenlader versucht, die Klasse zu laden, konnte sie aber nicht bekommen. Wird ausgelöst etwa von Class.forName(String).
  • InstantiationException: Der Versuch, ein Exemplar aufzubauen, scheitert, etwa wenn versucht wird, eine abstrakte Klasse zu instanziieren oder den Standardkonstruktor aufzurufen, die Klasse aber nur parametrisierte Konstruktoren deklariert.
  • IllegalAccessException: Die Sichtbarkeit ist zum Beispiel private, sodass von außen ein Attribut nicht erfragt, eine Methode nicht aufgerufen oder ein Exemplar nicht aufgebaut werden kann.
  • InvocationTargetException: Eine Methode oder ein Konstruktor können eine Exception auslösen. Die InvocationTargetException packt diese Exception ein.

Abbildung

Abbildung 18.1: UML-Diagramm für ReflectiveOperationException

Einige Methoden lösen weniger Ausnahmen im Fehlerfall aus, einige mehr. newInstance() führt gleich vier Ausnahmen am throws auf. Oftmals führt das zu großen catch-Blöcken mit dupliziertem Code. Ab Java 7 gibt es daher für die sechs Ausnahmen eine Oberklasse ReflectiveOperationException, sodass bei identischer Behandlung alles vom Typ ReflectiveOperationException gecatcht werden kann:

  • ClassNotFoundException extends ReflectiveOperationException
  • IllegalAccessException extends ReflectiveOperationException
  • InstantiationException extends ReflectiveOperationException
  • InvocationTargetException extends ReflectiveOperationException
  • NoSuchFieldException extends ReflectiveOperationException
  • NoSuchMethodException extends ReflectiveOperationException

ReflectiveOperationException selbst ist eine Unterklasse von Exception und nicht von RuntimeException. Sie muss daher explizit behandelt werden, genauso wie die anderen Ausnahmen vorher.


Rheinwerk Computing - Zum Seitenanfang

18.3.1 Reflections – Gespür für die Attribute einer KlasseZur nächsten ÜberschriftZur vorigen Überschrift

Besonders bei Klassen-Browsern oder GUI-Buildern ist es interessant, auf die Variablen eines Objekts zuzugreifen, das heißt, ihre Werte auszulesen und zu verändern. Damit wir an beschreibende Objekte für die in einer Klasse deklarierten beziehungsweise aus Oberklassen geerbten Variablen gelangen, rufen wir die Methode getFields() für das Class-Objekt der Klasse auf, die uns interessiert. Als Ergebnis erhalten wir ein Array von Field-Objekten. Jeder Array-Eintrag beschreibt eine Objekt- oder Klassenvariable, auf die wir zugreifen dürfen. Nur auf öffentliche, also public-Elemente, haben wir per (gewöhnlicher) Reflection Zugriff (auf eine privilegierte Reflection gehen wir hier nicht ein). Schnittstellen deklarieren ja bekanntlich nur Konstanten. Somit ist der schreibende Zugriff, den wir später näher betrachten wollen, nur auf in Klassen deklarierte Variablen beschränkt. Lesen ist natürlich bei Konstanten und Variablen gleichermaßen erlaubt. Beim Zugriff auf die Attribute mittels getFields() müssen wir aufpassen, dass wir uns keine SecurityException einfangen. Das kann uns aber bei vielen Methoden passieren, und weil SecurityException eine RuntimeException ist, muss sie auch nicht extra aufgefangen werden. In der Dokumentation ist sie daher nicht angegeben.

Um für SimpleDateFormat alle Objekt- und Klassenvariablen mit ihren Datentypen herauszufinden, lassen wir eine Schleife über das Field-Array laufen. Die Namen der Variablen finden sich leicht mit getName(). Wir haben aber den zugehörigen Datentyp noch nicht. Dazu müssen wir erst mit getType() ein Class-Objekt für den Typ ermitteln, und dann liefert uns getName() eine String-Repräsentation des Typs:

Listing 18.7: com/tutego/insel/meta/ShowFields.java, main()

Class<?> c = java.text.SimpleDateFormat.class;
System.out.println( "class " + c.getName() + " {" );
for ( Field publicField : c.getFields() ) {
String fieldName = publicField.getName();
String fieldType = publicField.getType().getName();
System.out.printf( " %s %s;%n", fieldType, fieldName );
}
System.out.println( "}" );

Dies ergibt die (gekürzte) Ausgabe:

class java.text.SimpleDateFormat {
int ERA_FIELD;
int YEAR_FIELD;
...
int SHORT;
int DEFAULT;
}
final class java.lang.Class<T>
implements Serializable, GenericDeclaration, Type, AnnotatedElement
  • Field[] getFields()
    Liefert ein Array mit Field-Objekten. Die Einträge sind unsortiert. Das Array hat die Länge 0, wenn die Klasse beziehungsweise Schnittstelle keine öffentlichen Variablen deklariert oder erbt. getFields() liefert automatisch auch Einträge für die aus Oberklassen beziehungsweise Schnittstellen geerbten öffentlichen Variablen.
  • Field getField(String name) throws NoSuchFieldException
    Erfragt ein bestimmtes Feld.

Die Klasse Field implementiert im Übrigen das Interface Member und ist eine Erweiterung von AccessibleObject. AccessibleObject ist die Basisklasse für Field-, Method- und Constructor-Objekte. Auch Method und Constructor implementieren das Interface Member, das zur Identifikation über getName() oder getModifiers() dient. Zusätzlich liefert getDeclaringClass() das Class-Objekt, das tatsächlich eine Variable oder Methode deklariert. Da geerbte Elemente in der Aufzählung mit auftauchen, ist dies der einzige Weg, um die Position der Deklaration in der Vererbungshierarchie exakt zu bestimmen.

Mit dem Field-Objekt können wir vieles erfragen: den Namen des Attributs, den Datentyp und auch wieder die deklarierten Modifizierer. Werfen wir einen Blick auf die toString()-Methode der Klasse Field:

public String toString() {
int mod = getModifiers();
return (((mod == 0) ? "" : (Modifier.toString(mod) + " "))
+ getTypeName(getType()) + " "
+ getTypeName(getDeclaringClass()) + "."
+ getName());
}
Beispiel

Für die Schleife über die Field-Objekte von SimpleDateFormat und einen Aufruf von toString() liefern die Zeilen

for ( Field publicField : c.getFields() )
System.out.println( " " + publicFields );

dann:

class java.text.SimpleDateFormat {
public static final int java.text.DateFormat.ERA_FIELD
public static final int java.text.DateFormat.YEAR_FIELD
...
public static final int java.text.DateFormat.SHORT
public static final int java.text.DateFormat.DEFAULT
}

final class java.lang.reflect.Field
extends AccessibleObject
implements Member
  • Class<?> getDeclaringClass()
    Liefert das Class-Exemplar für die Klasse oder die Schnittstelle, in der die Variable deklariert wurde. Diese Methode ist Teil der Schnittstelle Member.
  • int getModifiers()
    Liefert die deklarierten Modifizierer für die Variable.
  • String getName()
    Liefert den Namen der Variable. Diese Methode ist Teil der Schnittstelle Member.
  • Class<?> getType()
    Liefert ein Class-Objekt, das dem Datentyp der Variable entspricht.
  • String toString()
    Liefert eine String-Repräsentation. Am Anfang stehen die Sichtbarkeitsmodifizierer (public, protected oder private), und es folgen die weiteren Modifizierer (static, final, transient, volatile). Dann kommt der Datentyp, gefolgt vom voll qualifizierten Namen der deklarierenden Klasse, und schließlich der Name der Variable.

Abbildung

Abbildung 18.2: UML-Diagramm mit den Unterklassen von Member


Rheinwerk Computing - Zum Seitenanfang

18.3.2 Methoden einer Klasse erfragenZur nächsten ÜberschriftZur vorigen Überschrift

Um herauszufinden, über welche Methoden eine Klasse verfügt, wenden wir eine ähnliche Vorgehensweise an wie bei den Variablen: getMethods(). Diese Methode liefert ein Array mit Method-Objekten. Über ein Method-Objekt lassen sich Methodenname, Ergebnistyp, Parametertypen, Modifizierer und eventuell resultierende Exceptions erfragen. Wir werden später sehen, dass sich die durch ein Method-Exemplar repräsentierte Methode über invoke() aufrufen lässt.

Hinweis

Auch wenn zwei Klassen die gleiche Methode besitzen, muss doch ein Method-Objekt immer für jede Klasse erfragt werden. Method-Objekte sind immer mit dem Class-Objekt verbunden.

final class java.lang.Class<T>
implements Serializable, GenericDeclaration, Type, AnnotatedElement
  • Method[] getMethods()
    Gibt ein Array von Method-Objekten zurück, die alle öffentlichen Methoden der Klasse/Schnittstelle beschreiben. Geerbte Methoden werden mit in die Liste übernommen. Die Elemente sind nicht sortiert, noch gibt es keine Reihenfolge. Die Länge des Arrays ist null, wenn es keine öffentlichen Methoden gibt.
  • Method getMethod(String name, Class... parameterTypes)
    throws NoSuchMethodException

    Liefert zu einem Methodennamen und einer Parameterliste das passende Method-Objekt oder löst eine NoSuchMethodException aus. Besitzt die Methode keine Parameter – wie eine übliche getXXX()-Methode –, ist das Argument null und wird wegen der Varargs auf Class[] angepasst.

Nachdem wir nun mittels getMethods() ein Array von Method-Objekten erhalten haben, lassen die Method-Objekte verschiedene Abfragen zu. So liefert getName() den Namen der Methode, getReturnType() den Ergebnistyp, und getParameterTypes() erzeugt ein Array von Class-Objekten, das die Typen der Methodenparameter widerspiegelt. Wir kennen dies schon von den Attributen.

Wir wollen nun ein Programm betrachten, das alle Methoden und ihre Parametertypen sowie Ausnahmen ausgibt:

Listing 18.8: com/tutego/insel/meta/ShowMethods.java

package com.tutego.insel.meta;

import java.lang.reflect.*;

class ShowMethods
{
public static void main( String[] args )
{
showMethods( java.awt.Color.BLACK );
}

static void showMethods( Object o )
{
for ( Method method : o.getClass().getMethods() )
{
String returnString = method.getReturnType().getName();
System.out.print( returnString + " " + method.getName() + "(" );

Class<?>[] parameterTypes = method.getParameterTypes();

for ( int k = 0; k < parameterTypes.length; k++ ) {
String parameterString = parameterTypes[k].getName();
System.out.print( " " + parameterString );

if ( k < parameterTypes.length – 1 )
System.out.print( ", " );
}
System.out.print( " )" );

Class<?>[] exceptions = method.getExceptionTypes();

if ( exceptions.length > 0 ) {
System.out.print( " throws " );
for ( int k = 0; k < exceptions.length; k++ ) {
System.out.print( exceptions[k].getName() );
if ( k < exceptions.length – 1 )
System.out.print( ", " );
}
}

System.out.println();
}
}
}

Die Ausgabe sieht gekürzt so aus:

int hashCode( )
boolean equals( java.lang.Object )
java.lang.String toString( )
...
[F getRGBColorComponents( [F )
...
void wait( long ) throws java.lang.InterruptedException
void notify( )
void notifyAll( )

Wir bemerken an einigen Stellen eine kryptische Notation, wie etwa »[F«. Dies ist aber lediglich wieder die schon erwähnte Kodierung für Array-Typen. So gibt getRGB-Components() ein float-Array zurück und erwartet ein float-Array als Argument.

final class java.lang.reflect.Method
extends AccessibleObject
implements GenericDeclaration, Member
  • Class<?> getDeclaringClass()
    Liefert das Class-Exemplar für die Klasse oder die Schnittstelle, in der die Methode deklariert wurde. Diese Methode ist Teil der Schnittstelle Member.
  • String getName()
    Liefert den Namen der Methode. Diese Methode ist Teil der Schnittstelle Member.
  • int getModifiers()
    Liefert die Modifizierer. Diese Methode ist Teil der Schnittstelle Member.
  • Class<?> getReturnType()
    Gibt ein Class-Objekt zurück, das den Ergebnistyp beschreibt.
  • Class<?>[] getParameterTypes()
    Liefert ein Array von Class-Objekten, die die Typen der Parameter beschreiben. Die Reihenfolge entspricht der deklarierten Parameterliste. Das Array hat die Länge null, wenn die Methode keine Parameter erwartet.
  • Class<?>[] getExceptionTypes()
    Liefert ein Array von Class-Objekten, die mögliche Exceptions beschreiben. Das Array hat die Länge null, wenn die Methode keine solchen Exceptions mittels throws deklariert. Das Feld spiegelt nur die throws-Klausel wider. Sie kann prinzipiell auch zu viele Exceptions enthalten, bei einer Methode foo() throws RuntimeException, NullPointerException etwa genau die beiden Ausnahmen.
  • String toString()
    Liefert eine String-Repräsentation der Methode, ähnlich dem Methodenkopf in einer Deklaration.

Rheinwerk Computing - Zum Seitenanfang

18.3.3 Properties einer Bean erfragenZur nächsten ÜberschriftZur vorigen Überschrift

Eine Bean besitzt Properties (Eigenschaften), die in Java (bisher) durch Setter und Getter ausgedrückt werden, also Methoden, die einer festen Namenskonvention folgen. Gibt es Interesse an den Properties, lässt sich natürlich getMethods() auf dem Class-Objekt aufrufen und nach den Methoden filtern, die der Namenskonvention entsprechen. Die Java-Bibliothek bietet aber im Paket java.beans eine einfachere Lösung für Beans: einen PropertyDescriptor.

Beispiel

Gib alle Properties von Color aus (es gibt nur lesbare):

Listing 18.9: com/tutego/insel/meta/PropertyDescriptors.java, main()

BeanInfo beanInfo = Introspector.getBeanInfo( Color.class );
for ( PropertyDescriptor pd : beanInfo.getPropertyDescriptors() )
System.out.println( pd.getDisplayName() + " : " +
pd.getPropertyType().getName() );

Die Ausgabe:

RGB : int
alpha : int
blue : int
class : java.lang.Class
colorSpace : java.awt.color.ColorSpace
green : int
red : int
transparency : int

Interessanter sind vom PropertyDescriptor die Methoden getReadMethod() und getWriteMethod(), die beide ein Method-Objekt liefern – sofern es verfügbar ist –, um so die Methode gleich aufrufen zu können.

BeanInfo liefert mit getPropertyDescriptors() zwar die Properties, kann jedoch über getMethodDescriptors() auch alle anderen Methoden liefern.


Rheinwerk Computing - Zum Seitenanfang

18.3.4 Konstruktoren einer KlasseZur nächsten ÜberschriftZur vorigen Überschrift

Konstruktoren und Methoden haben einige Gemeinsamkeiten, unterscheiden sich aber insofern, als Konstruktoren keinen Rückgabewert haben. Die Ähnlichkeit zeigt sich auch in der Methode getConstructors(), die ein Array von Constructor-Objekten zurückgibt. Über dieses Array lassen sich dann wieder Name, Modifizierer, Parameter und Exceptions der Konstruktoren einer Klasse erfragen. Wie wir in Abschnitt 18.4.1, »Objekte erzeugen«, sehen werden, lassen sich auch über die Methode newInstance() neue Objekte erzeugen. Wegen der weitgehenden Ähnlichkeit der Klassen Constructor und Method sind die folgenden Methoden hier nicht näher beschrieben.

Beispiel

Zeige alle Konstruktoren der Color-Klasse:

Listing 18.10: com/tutego/insel/meta/ShowConstructors.java, main()

for ( Constructor<?> c : java.awt.Color.class.getConstructors() )
System.out.println( c );

Die Klasse Constructor implementiert eine auskunftsfreudige toString()-Methode. Die String-Repräsentation zeigt die Signatur mit Sichtbarkeit. Nach dem Aufruf erhalten wir:

public java.awt.Color(float,float,float,float)
public java.awt.Color(int)
public java.awt.Color(int,int,int)
public java.awt.Color(int,int,int,int)
public java.awt.Color(java.awt.color.ColorSpace,float[],float)
public java.awt.Color(int,boolean)
public java.awt.Color(float,float,float)

final class java.lang.Class<T>
implements Serializable, GenericDeclaration, Type, AnnotatedElement
  • Constructor[] getConstructors()
    Liefert ein Feld mit Constructor-Objekten.
  • Constructor<T> getConstructor(Class... parameterTypes)
    throws NoSuchMethodException
    Liefert ein ausgewähltes Constructor-Objekt.
final class java.lang.reflect.Constructor<T>
extends AccessibleObject
implements GenericDeclaration, Member
  • Class<T> getDeclaringClass()
    Eine ziemlich langweilige Methode, da Konstruktoren nicht vererbt werden. Sie gibt immer nur jene Klasse aus, von der das Class-Objekt kommt. Das ist ein wichtiger Unterschied zwischen Methoden und Konstruktoren, der bei dieser Methode deutlich auffällt.
  • Class[] getExceptionTypes()
  • int getModifiers()
  • String getName()
  • Class[] getParameterTypes()

Abbildung

Abbildung 18.3: UML-Diagramm mit den Unterklassen von Member


Rheinwerk Computing - Zum Seitenanfang

18.3.5 AnnotationenZur vorigen Überschrift

Annotationen erfragen Methoden der Schnittstelle AnnotatedElement, die unter anderem Class, Constructor, Field, Method und Package implementieren. Ein Blick in AnnotatedElement verrät, wie an die Annotationen heranzukommen ist:

interface java.lang.reflect.AnnotatedElement
  • Annotation[] getAnnotations()
    Liefert alle mit diesem Element assoziierten Annotationen.
  • Annotation[] getDeclaredAnnotations()
    Liefert alle an diesem Element deklarierten Annotationen. Vererbte Annotationen werden ignoriert.
  • boolean isAnnotationPresent(Class<? extends Annotation> annotationType)
    Erfragt, ob das Element eine bestimmte Annotation besitzt.
  • <T extends Annotation> T getAnnotation(Class<T> annotationType)
    Liefert die Annotationen eines gewünschten Typs.

In Abschnitt 18.5, »Eigene Annotationstypen«, kommen wir auf Annotationen zurück.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
  Zum Katalog
Neuauflage: Java SE 8 Standard-Bibliothek
Neuauflage: Java SE 8 Standard-Bibliothek
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Java EE 7






 Professionell
 entwickeln mit
 Java EE 7


Zum Katalog: Java ist auch eine Insel






 Java ist auch
 eine Insel


Zum Katalog: Einstieg in Eclipse






 Einstieg in Eclipse


Zum Katalog: Einstieg in Java






 Einstieg in Java


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de