Java
Links und Literatur
- Java ist auch eine Insel
- Java in 21 Tagen
- Handbuch der Java-Programmierung
- Angelika Langer: JAVA
- Java Classpath
- Effective Java von Joshua Bloch
Java Aufruf
Java mit mehr Speicher starten
Bestimmte Java Version erzwingen
Java Programm compilieren und ausführen
Achtung, das Trennzeichen unter Windows ist nicht ":" sondern ";".
So erzeugt man aus einer .java Datei eine .class Datei
Dabei muss man alle jar Dateien angeben, die direkt von der Klasse genutzt werden (also nicht die, die nur von Klassen genutzt werden, die wir aufrufen).
So erzeugt man jar Dateien
Siehe auch die JAR Dateien erzeugen Anleitung.
So führt man das Java Programm dann aus (jetzt muss man wirklich all jars auflisten die zur Ausführung gebraucht werden)
Java debuggen
So kann man auf einem entfernten Rechner Java so starten, dass es im lokalen Debugger untersucht werden kann
Dabei sorgt
Um den Debugger einzurichten, in Eclipse
remote java application
new
Rechnername und Port des Java Programms
Data Containers
Java Classes
Autoboxing
Integer j = i; // j = Integer.valueOf(i)
int k = j; // k = j.intValue()
Gleichheit
Foo a, b;
x==y // (1)
a==b // (2)
a.equals(b); (3)
(1) Bei Basistypen ein normaler Test auf Gleichheit (2) Ansonsten Test ob beides eine Referenz auf das gleiche Objekt ist (3) Inhaltliche Gleichheit mit equals() testen
Wenn man equals nicht selbst implementiert sieht es so aus: und equals selbst implementieren, default ist das:
{
return ( this == obj );
}
Eine mögliche Implementierung:
{
if ( obj instanceof Foo ) {
Foo tmp = (Foo) obj;
return (bar == tmp.bar)
}
return super.equals( obj );
}
Als Parameter aber Object erwarten und nicht die Klasse für die die Methode gedacht ist. Also nicht:
Achtung, wenn man equals ändert, darauf achten, dass aus a.equals(b) auch a.hashcode()==b.hashcode() folgen muss (umgekehrt aber nicht). Eclipse kann für equals() und hashcode() sinnvolle Vorschläge machen.
Achtung, die Reihenfolge beim equals() Vergleich ist z.B. dann relevant, wenn einer der beiden Objekte null werden kann. Ist z.B. a potentiell null, b hingegen nicht, kann man das equals von a natürlich nicht aufrufen
b.equals(a);
Können beide null sein, diesen Fall vorher extra abfangen (sonst gibt es eine Exception wenn versucht wird equals auf null aufzurufen).
Conditional Expressions
Kurzschreibweise für bedingte Zuweisung
int max=(ungerade) ? l : l-1;
Vorsicht bei conditional operator x ? y : z wenn y und z verschiedene Typen haben, vor allem wenn y oder z keinen konstanten Wert haben oder nicht vom Typ byte short char sind, dann tritt eine Konvertierung in Kraft mit möglicherweise unerwartetem Ergebnis.
Kurzschlußoperatoren
boolean b2 = true | foo(); // (2)
boolean b3 = false & foo(); // (3)
(1) foo() wird nicht aufgerufen (2) foo() wird aufgerufen (3) foo() wird aufgerufen
Compound Assignment Operator
x+=y; //B
x=+y; //C
Dabei ist B ist bekannt als Kurzschreibweise für A, allerdings unterscheidet sich B im Verhalten leicht von A, da in Java bei B versucht wird, durch einen Cast den Typ von y auf den Typ von x anzupassen.
Das hier ist z.B. valider Java Code
int y=128;
x+=y;
Das hier hingegen nicht
int y=128;
x=x+y;
Allerdings liefert der versteckte Cast denoch ein vermutlich unerwartetes Ergebnis, weil 128 gar nicht in eine byte Variable passt.
Umgekehrt unterliegt B aber auch Einschränkungen, denen A nicht unterliegt. So muss in B x ein primitiver (boxed) Datentyp oder String sein.
String y = "World";
x = x + y; // OK
x += y; // Error
C sieht so ähnlich aus wie B weißt aber einfach nur x den Wert von y zu (ohne das Vorzeichen von y irgendwie zu verändern).
Undefinierte Parameter Anzahl
Methoden können eine undefinierte Anzahl an Parametern erwarten, ansprechbar wie ein Array
{
System.out.println(x.lenght);
}
Überdeckte Namen
{
x = 12; // (1)
this.x = 12; // (2)
this.x=x;
}
(1) Zuweisung an lokale Variable x (2) Zuweisung an Objektvariable x
Override
Optional erklären dass man eine Methode des Vaters überschreibt (Fehler falls nicht)
public void foo( int alter )
Lazy Initialization
Die Initialisierung wird hinausgezögert, bis sie wirklich gebraucht wird.
Anstatt also ein Attribut sofort mit einem Wert zu belegen
Verzögert man das, bis der Wert erstmalig ausgelesen wird
public synchronized Integer getFoo()
{
if(foo==null) foo=initFoo();
return foo;
}
Für statische Attribute gibt es einen eleganten Trick. Man nutzt eine kleine statische Klasse, die nur das Attribut und dessen Initialisierung enthält. Erst wenn dieses Attribut zum ersten Mal benutzt wird, wird auch die Klasse zum ersten Mal benutzt und die Initialisierung läuft an. Ein manuelles synchronized ist nicht notwendig.
{
static final Integer foo = initFoo();
}
static Integer getFoo()
{
return FooHolder.foo;
}
Wenn man ein nicht statisches Attribut hat und vermeiden will, und Performance Verluste mit einem synchronized Getter vermeiden will, kann man das double-check idiom verwenden
public Integer getFoo()
{
Integer tmp=foo;
if(tmp==null)
{
synchronized(this)
{
tmp=foo;
if(tmp==null) foo=tmp=initFoo();
}
}
return tmp;
}
Wichtig ist, dass das Attribut volatile ist, damit Änderungen von einem Thread von allen Threads gesehen werden. Sollte ein Thread das Attribut nicht initialisiert vorgefunden haben, testet er das nochmal, nur diesmal synchronized, damit wird verhindert, dass mehr als einmal initialisiert wird. Falls eine mehrfache initialisierung nicht stört, kann man diesen Schritt auch weglassen, das nennt man dann single-check idiom.
Die lokale Variable tmp ist nicht zwingend notwendig, verbessert aber die Performance.
final
Variable nicht änderbar (wohl aber Methoden aufrufbar die sie ändern)
final Foo y=new Foo();
y.reset();
Erben nicht möglich
{
// ...
}
Überschreiben nicht möglich
{
final void bar();
}
Generische Datentypen / Generics
{
private T val;
void setValue( T val )
{
this.val = val;
}
T getValue()
{
return val;
}
}
Foo<String> stringFoo = new Foo<String>();
Foo<Integer> intFoo = new Foo<Integer>();
Foo<Point> pointFoo = new Foo<Point>();
class Bar
{
public static <T extends Number> T myMethod( T a, T b, HashMap<T, String> )
{
//...
}
}
So kann man von einer generischen Klasse erben, ohne deren generischen Typ weiter einzuschränken.
Macht man das falsch erhält man oft diesen Fehler
Manchmal will man den Typen dabei aber auch weiter einschränken. Hier ein Beispiel wie es geht. Angenommen man hat eine einfache Klassenhierarchie, z.B. verschiedene Hunde
{
public void bark()
{
System.out.println("Wuff!");
}
}
public class Poodle extends Dog
{
public void barkLikeAPoddle()
{
System.out.println("Wuff, Wuff!");
}
}
public class FrenchPoodle extends Poodle
{
public void barkLikeAFrenchPoddle()
{
System.out.println("Wüff, Wüff!");
}
}
Und jetzt möchte man parallel dazu eine weitere Klassenhierarchie haben. Diese neue Hierarchie soll jetzt mit der ersten verbunden werden. Bestimmte Stufen der neuen Hierarchie arbeiten nur mit bestimmten Klassen der ersten Hierarchie zusammen. Eine Möglichkeit das abzubilden sind Generics. Zum Beispiel soll es jetzt verschiedene Hundehütten geben, die nur bestimmte Hunde akzeptieren.
{
protected T dogInTheHouse;
public void wakeTheDog()
{
this.dogInTheHouse.bark();
}
}
Trickreich sind hier die Zwischenklassen, die bereits von einer anderen Klasse mit Einschränkung auf den Typ erben, sich aber auf den Typ noch nicht final festlegen. Besondern schwierig ist es, in einer solchen Zwischenklasse neue Objekte des eingebetteten Typs zu erzeugen, weil die Klasse nie wissen kann, für welchen Typ sie später benutzt wird.
{
public void wakeTheDog()
{
this.dogInTheHouse.bark();
this.dogInTheHouse.barkLikeAPoddle();
}
public void assignementIsEasy(T newDog)
{
this.dogInTheHouse=newDog;
}
/*
public void butCreationIsTricky()
{
this.dogInTheHouse=new Dog(); // Fails because T might be Poodle
this.dogInTheHouse=new Poodle(); // Fails because T might be FrenchPoodle
this.dogInTheHouse=new FrenchPoodle(); // Fails because T might be something which also extends Poodle
}
*/
}
Das ist wieder leicht:
{
public void wakeTheDog()
{
this.dogInTheHouse.bark();
this.dogInTheHouse.barkLikeAPoddle();
this.dogInTheHouse.barkLikeAFrenchPoddle();
}
}
Javadoc
* @see Bar
* @link Bar
* @version 1.01
* @author John Doe
* @param x A number
* @param y Another number
* @return This method always returns 5
* @exception NumberFormatException
* @throws NumberFormatException
* @category Setter
* @deprecated Since yesterday
*/
public int foo(int x, float y)
{
return 5;
}
Exceptions
{
// ...
return 5;
}
catch ( Exception e )
{
System.err.println( "Error");
}
finally
{
... // (1)
// return 7; (2)
}
(1) auf jeden Fall, auch nach dem return (2) keine Exception kann nach oben durchgereicht werden
Wann wird finally ausgeführt
In diesem Beispiel nutzen alle return Anweisungen eine Methode um den Rückgabewert zu ermitteln. Dadurch kann man dokumentieren, wann die einzelnen return Anweisungen aufgerufen werden
{
System.out.println("Here is your String value: "+pValue);
return pValue;
}
@SuppressWarnings("finally")
public static String doSomething(boolean pDoException)
{
System.out.println("Method entered");
try
{
System.out.println("Try block entered");
if(pDoException) throw new Exception("Bang!");
return getStringValueAndLogIt("NormalReturn");
}
catch(Exception e)
{
System.out.println("Exception occured");
return getStringValueAndLogIt("ExceptionReturn");
}
finally
{
System.out.println("Finally block entered");
// do not use return in a finally block!
return getStringValueAndLogIt("FinallyReturn");
}
}
Falls keine Exception auftritt:
Try block entered
Here is your String value: NormalReturn
Finally block entered
Here is your String value: FinallyReturn
Falls eine Exception auftritt
Try block entered
Exception occured
Here is your String value: ExceptionReturn
Finally block entered
Here is your String value: FinallyReturn
Man sieht also, in beiden Fällen wird erst das return aufgerufen und dann erst den finally Block. Das ist auch sehr sinnvoll, weil natürlich auch das return Statement eine Exception auslösen könnte. Da der finally Block selbst wieder ein return enthält (was man tunlichst vermeiden sollte) setzt dieser sich am Ende durch und die Methode liefert in beiden Fällen
zurück.
Eigene Exceptions
{
public ClubException()
{
}
public ClubException( String s )
{
super( s );
}
}
Stacktrace
[[http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstack.html | jstack ]] PID;
Thread.dumpStack();
Assert
Sicherstellen dass die gegebene Bedingung erfüllt ist
Überwachung der Assertions aktivieren
java -enableassertions:bar foo
Multithreading
Dateien und Verzeichnisse
Java is auch eine Insel: Dateien und Verzeichnisse.
JSON
Create a class to hold the values, e.g. for a person, add annotations to its constructor
import com.fasterxml.jackson.annotation.JsonProperty;
public class Person {
private final String name;
private final Integer age;
@JsonCreator
public Person(@JsonProperty("name") final String name, @JsonProperty("age") final Integer age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
Turn an object into a JSON String, and a JSON String into an object
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
public class JsonPlay {
public static void object2JsonString() throws JsonProcessingException {
// http://www.studytrails.com/java/json/jackson-create-json.jsp
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
mapper.setSerializationInclusion(Include.NON_EMPTY);
final Person john = new Person("John Jones", 42);
final String jsonString = mapper.writeValueAsString(john);
// { "name" : "John Jones", "age" : 42 }
System.out.println(jsonString);
}
public static void jsonString2Object() throws JsonParseException, IOException {
final String json = "{ \"name\" : \"John Jones\", \"age\" : 42 }";
final ObjectMapper mapper = new ObjectMapper();
final Person john = mapper.readValue(json, Person.class);
System.out.println(john);
}
You might want to control the serialization or de-serialization of a field or even of a whole class
@JsonDeserialize(using = Foo.CustomDeSerializer.class)
public class Foo {
...
public Foo() {
}
static class CustomDeSerializer extends JsonDeserializer<Foo> {
ObjectMapper mapper=new ObjectMapper();
@Override
public Foo deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
Foo result=new Foo();
JsonNode node = parser.getCodec().readTree(parser);
Iterator<Entry<String, JsonNode>> iter = node.fields();
while(iter.hasNext()) {
Entry<String, JsonNode> node = iter.next();
result.set...
}
return result;
}
}
static class CustomSerializer extends JsonSerializer<Foo> {
@Override
public void serialize(Foo value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
...
jgen.writeBooleanField("...", ...);
...
jgen.writeEndObject();
}
}
}
Watch out if you try to create json out of an object that has a Map with a non trivial key typ. That is a mess. Maybe try to have String or enum instead
https://www.baeldung.com/jackson-map
Java XML
CSV Dateien auslesen
...
CSVReader reader = new CSVReader("Foo.csv", ',');
List<String[]> myEntries = reader.readAll();
Excel Dateien schreiben und lesen
import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
...
XSSFWorkbook workbook=new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("My Excel Sheet");
XSSFRow row0 = sheet.createRow(0);
{
XSSFCell cell0 = row0.createCell(0);
XSSFCell cell1 = row0.createCell(1);
cell0.setCellValue(“Number”);
cell1.setCellValue(“Date”);
}
XSSFRow row1 = sheet.createRow(1);
{
XSSFCell cell3 = row1.createCell(1);
cell3.setCellValue(42);
XSSFCell cell4 = row1.createCell(2);
cell4.setCellValue(new Date());
XSSFCellStyle cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(workbook.getCreationHelper().createDataFormat().getFormat("yyyy-mm-dd"));
cell4.setCellStyle(cellStyle);
}
sheet.autoSizeColumn(0);
sheet.autoSizeColumn(1);
File output=new File(“excelfile.xlsx);
FileOutputStream out = new FileOutputStream(output);
workbook.write(out);
out.close();
Access file located in the classpath
if(url!=null)
{
return url.getPath();
}
This would look for the file directly in src/main/resources. However, you should create subfolders there matching the class package (e.g. if the package would be de.tgunkel.java create de/tgunkel/java/) and put the file there. In order to access it there use (without getClassLoader)
Add / in front of the the filename would again access files in the root folder.
You should avoid to get the URL first and then try to read it but use getResourceAsStream to directly get a stream, no matter how wired the URL might be (e.g. a file inside a JAR)
Example
try (InputStream in = getClass().getResourceAsStream(filename)) {
final String myString = IOUtils.toString(in, "UTF-8");
return myString;
}
}
Reguläre Ausdrücke
Häufig möchte man aus einem String bestimmte Teile ausschneiden und dann neu zusammensetzen. Ein typisches Beispiel ein Datum liegt in dieser Form vor
und soll in diese Form übertragen werden
Mit einer sogenannten Backreference kann man jetzt Tag, Monat und Jahr erst durch einen regulären Ausdruck erfassen und Klammern. Danach dann via $1, $2, $3 wieder ausgeben lassen
Und schon hat man ein Format welches Date versteht
Aus einem String eine Regexp erzeugen, die auf diesen String passt (nützlich um Escape Zeichen zu erzeugen) String s=java.util.regex.Pattern.quote("Hallo Welt");
Ein Trick zum Escapen eines ganzen Bereiches geht übrigens so
Reflection
try
{
c = Class.forName("foo");
} catch (ClassNotFoundException ex)
{
// ...
}
Annotations
So macht man seine eigene Annotation
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface XMLGeneratorAnnotation
{
String elementName() default "";
int elemntOrder() default 0;
}
So ermittelt man alle Attribute eines Objektes und seine Werte
{
f.setAccessible(true);
MyAnnotation a=f.getAnnotation(MyAnnotation.class);
try
{
f.getName();
f.get(myObject);
}
catch (IllegalArgumentException | IllegalAccessException e)
{
}
finally
{
}
}
So ermittelt man alle Methoden eines Objektes und ruft sie auf
{
m.setAccessible(true);
ElementContainer container=new ElementContainer();
MyAnnotation a=m.getAnnotation(MyAnnotation.class);
try
{
m.getName();
m.invoke(myObject);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
}
finally
{
}
}
Apache Commons
Nützliche Java Komponenten Apache Commons.
Objekte in Strings umwandeln
String in Zahl konvertieren
0 Padding
So kann man den String year mit führenden Nullen auf 4 Stellen auffüllen:
Syntax:
Flags '0' (0 Padding) Conversion 'd' Integer, 'f' Float, 't' date, 'T' Time
Binärdarstellung
Siehe
Long.toBinaryString(number);
Long.toBinaryString(Double.doubleToRawLongBits(number));
Java Properties
Über Properties kann man leicht Parameter zur Konfiguration einer Anwendungen setzen und lesen (ähnlich dem setzen einer Systemvariable wie z.B. PATH). So kann man in Java leicht Properties auslesen
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
...
// System properties (java -Dvariable=value)
Properties systemProperties=System.getProperties();
// Properties found in a file in the classpath, will also
// contain the values from the system properties
Properties fileProperties =new Properties(systemProperties);
URL url = ClassLoader.getSystemResource("MyProperties.properties");
fileProperties.load(new FileInputStream(new File(url.getFile())));
// Properties we will fill with the code during runtime
// will also contain the file properties (and with them also
// the system properties)
Properties extraProperties =new Properties(fileProperties);
// changes to the top level properties objects ...
systemProperties.setProperty("test.helloworld", "Hello world");
// ... are also reflected in their children
String message=extraProperties.getProperty("test.helloworld");
// debug output
extraProperties.list(System.out);
Java Preferences
Über Preferences kann man leicht Userbezogene Einstellungen abspeichern und später wieder laden. Dabei werden die Information im Hintergrund automatisch an einem zentralen Ort (pro User) abgelegt. Unter Windows z.B. in der Registry,
man selbst muss sich um den Ablageort nicht kümmern.
// read the already stored values
String name =prefsRoot.get( "name", "unknown");
Double weight =prefsRoot.getDouble( "weight", 0.0);
Boolean selected=prefsRoot.getBoolean("selected", false);
Long id= prefsRoot.getLong( "id", 0L);
// store new values
prefsRoot.put ("name", "John Doe");
prefsRoot.putDouble ("weight", 90.01);
prefsRoot.putBoolean("selected", true);
prefsRoot.putLong ("id", 1234567L);
JMX
Speichermodell in Java
Stack: Die lokalen und primitiven Variablen einer Methode werden im Stack gespeichert. Heap: Neu erzeugte Objekte landen im Eden Space / "young generation". Objekte dort werden statistisch oft erzeugt und schnell wieder aufgegeben. Nach einem Garbage Collector Lauf wandern alle Objekte, die ihn überlegt haben in den Survivor Space. Nach einigen Durchläufen landen die überlegebenden Objekte dann in der Tenured Generation / old generation. Das Verschieben der Objekte kostet zwar Aufwand, dafür können dabei aber wieder zusammenhänge Speicherbereiche entstehen. Non-heap memory: Thread übergreifender Speicher welchen die Java VM für interne Zwecke benötigt. Z.B. Informationen pro Klasse, Methode, Konstruktoren, aber auch Konstanten. Wird Permanent Generation genannt, obwohl der Speicher nicht permant sein muss. Hinzu kommt noch der Code Cache.
- Java Heap Terminology
- Java storage management
- Java memory pool
- Permsize
- Permgen
- No Permgen
- Garbage Collector Paper
GUI mit Java
Swing
Java in Internetseiten
Java Applet
Java wird beim Client ausgeführt Sun Java Applet Tutorial
import java.awt.Graphics;
public class HelloWorld extends JApplet
{
private static final long serialVersionUID = 1L;
public void init() {};
public void start() {};
public void stop() {};
public void paint(Graphics g)
{
g.drawRect(20, 20, getSize().width - 40, getSize().height - 40);
g.drawString("Hello world!", 40, 40);
}
public void destroy() {};
}
Wird so in HTML eingebettet
JavaServer Pages und Servlets
Java wird auf dem Server ausgeführt JavaServer Pages und Servlets
Verteilte Programmierung mit RMI und WebServices
Verteilte Programmierung mit RMI und WebServices
Bound Properties / PropertyChangeListener
Man möchte Code ausführen, wann immer sich in einer anderen Klasse (einer Bean) ein bestimmtes Attribut ändert. Dazu nimmt man sich die ganz normale Bean Klasse mit ihren Settern und Gettern. Die Klasse wird um ein PropertyChangeSupport Attribut ergänzt und in allen betroffenen Settern wird über diese Attribut in jedem relevanten Setter ein firePropertyChange ausgeführt. Außerdem wird noch die Möglichkeit geschaffen, dass man von außen einen PropertyChangeListener in dem PropertyChangeSupport Attribut registrieren kann.
{
private Long id;
private String name;
private Integer age;
private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport( this );
public void addPropertyChangeListener( PropertyChangeListener listener )
{
this.myPropertyChangeSupport.addPropertyChangeListener( listener );
}
public void removePropertyChangeListener( PropertyChangeListener listener )
{
this.myPropertyChangeSupport.removePropertyChangeListener( listener );
}
public Long getId()
{
return id;
}
public void setId(Long pId)
{
this.id = pId;
}
public String getName()
{
return name;
}
public void setName(String pName)
{
String lOldName=this.name;
this.name = pName;
this.myPropertyChangeSupport.firePropertyChange("name", lOldName, this.name);
}
public Integer getAge()
{
return age;
}
public void setAge(Integer pAge)
{
Integer lOldAge=this.age;
this.age = pAge;
this.myPropertyChangeSupport.firePropertyChange("age", lOldAge, this.age);
}
}
So sieht z.B. ein PropertyChangeListener aus, der nur ermittelt, wie das Attribut hieß, dass geändert wurde.
import java.beans.PropertyChangeSupport;
public class AttributeStalker implements PropertyChangeListener
{
@Override
public void propertyChange(PropertyChangeEvent evt)
{
String attributeName=evt.getPropertyName();
...
}
}
Und so benutzt man die Bean mit dem PropertyChangeListener
AttributeStalker s=new AttributeStalker();
b.addPropertyChangeListener(s);
b.setId(5l);
b.setName("Foo");
Java SSL
Der Inhalt der keystore Datei auflisten
Enter keystore password: ********
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
XXXX, 18.03.2014, PrivateKeyEntry,
Certificate fingerprint (SHA1): XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Ein jar mit jarsigner auf valide Signaturen überprüfen
- Understanding Signing and Verification
- Signing JAR Files
- Verifying Signed JAR Files
- JUnit
- JUnit test case generation
- JUnit test editor
- Dependency Analysis
- Code Audit
CORBA
Quartz
Java 7
Was ist eigentlich neu in Java 7?
Lesbare Konstanten
Konstanten können mit _ lesbarer gemacht werden und es ist möglich Binärkonstanten zu verwenden:
int one_million = 1_000_000;
int oneMillion = 1000000;
boolean equal=(one_million==oneMillion);
// add a binary constant 0b ...
int binaryNine=0b1001;
int nine=9;
boolean equal=(nine==binaryNine);
Switch mit Strings
In einem Switchblock können Strings verwendet werden
String result="String switch says the user is ";
switch(aString)
{
case "Foo":
result+="Mr. Foo";
break;
case "Bar":
result+="Mr. Bar";
break;
case JOHN:
result="John";
break;
default:
result="a surprise";
}
Diamond Operator
Es ist nicht mehr notwendig, den Datentyp bei der Instanziierung zu wiederholen
HashMap<Integer, String> prejva17=new HashMap<Integer, String>();
// Java 1.7
HashMap<Integer, String> products=new HashMap<>();
products.put(123456, "Gigant TV");
products.put(1, "DVD");
Mehr als eine Exception fangen
Man kann jetzt mehr als eine Exception auf einmal fangen und bearbeiten
{
if(bang==0)
{
throw new IllegalArgumentException();
}
else
{
throw new IllegalStateException();
}
}
// catch more than one exception at once
catch(IllegalArgumentException | IllegalStateException e)
{
System.out.println("got exception "+e);
}
Ressourcen Management
Bisher war es recht aufwendig mit Ressourcen umzugehen, die auch wieder geschlossen werden müssen
FileOutputStream fos=null;
try
{
fos=new FileOutputStream(filename);
// ...
}
catch (FileNotFoundException e)
{
e.printStackTrace();
// ...
throw new RuntimeException(e);
}
/* You needed a finally block to make sure your closeable resource
* is closed under all circumstances
*/
finally
{
try
{
if(fos!=null) fos.close();
} catch (IOException e)
{
e.printStackTrace();
// ...
throw new RuntimeException(e);
}
}
Jetzt können dieses Ressourcen automatisch geschlossen werden, wenn sie java.io.Closeable implementieren und innerhalb eines try Statements definiert und erzeugt werden:
* inside a try will automatically issue close()
* when the variable reaches its end of lifetime.
* Don't forget that even the implicit close()
* may issue an exception
*/
try(Closeable fos=new FileOutputStream(filename))
{
// ...
}
catch (IOException e) {
e.printStackTrace();
// ...
throw new RuntimeException(e);
}
Java 7 Links
- O'Reilly A look at Java 7's new features
- Joe Wright New language features in Java 7
- Oracle JDK 7 Adoption Guide
- Simon Koelsch Java 7
Java 8
Was ist eigentlich neu in Java 8?
Date
Annotations
Eine Annotation darf jetzt mehrfach gesetzt werden
@Foo("Value2")
class Person {}
Die Annotation dazu sieht so aus
@interface Foo {
String value();
}
Und hier werden dann bei Mehrfachnutzung die Einzelwerte abgelegt
Foo[] value();
}
Nullpointer
Angenommen man hat eine Klasse die eine Liste von Freunden beinhaltet, und jeder Freund hat wiederum einen Namen. Man kann also z.B. so auf einen Namen zugreifen
Allerdings kann es dabei an mehreren Stellen zu einer NullPointerException kommen, was aufwendige Tests darauf notwendig machen kann
friendsHolder.allFriends!=null &&
friendsHolder.allFriends.get(0)!=null &&
friendsHolder.allFriends.get(0).getName()!=null) {
}
So funktioniert das mit der neuen Optional Klasse
.flatMap(a -> Optional.ofNullable(a.allFriends))
.flatMap(b -> Optional.ofNullable(b.get(0)))
.flatMap(c -> Optional.ofNullable(c.getName()))
.ifPresent(System.out::println);
Concurrency Java 8
Nashorn JavaScript Engine for the JVM
Nashorn: A Next-Generation JavaScript Engine for the JVM