4. Vorab
•Blick über den Tellerrand
•Welche Probleme lösen wir auf welche Weise?
Sven Efftinge - itemis AG
5. Vorab
•Blick über den Tellerrand
•Welche Probleme lösen wir auf welche Weise?
•Wann und warum nutzen wir andere Lösungen (XML)?
Sven Efftinge - itemis AG
6. Vorab
•Blick über den Tellerrand
•Welche Probleme lösen wir auf welche Weise?
•Wann und warum nutzen wir andere Lösungen (XML)?
•Wie machen das andere Sprachen
Sven Efftinge - itemis AG
7. Vorab
•Blick über den Tellerrand
•Welche Probleme lösen wir auf welche Weise?
•Wann und warum nutzen wir andere Lösungen (XML)?
•Wie machen das andere Sprachen
•Rückwärtskompatibilität wird ignoriert
Sven Efftinge - itemis AG
10. Kommt Ihnen das bekannt vor?
public class Customer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Sven Efftinge - itemis AG
11. Kommt Ihnen das bekannt vor?
public class Customer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Oder das?
}
Customer c = new Customer();
c.setName(“foobar”);
//...
return c.getName();
Sven Efftinge - itemis AG
12. Kommt Ihnen das bekannt vor?
public class Customer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Oder das?
}
Customer c = new Customer();
c.setName(“foobar”);
//...
return c.getName();
Sven Efftinge - itemis AG
13. Warum nicht einfach Felder benutzen?
public class Customer {
public String name;
}
... und ...
Customer c = new Customer();
c.name = “foobar”;
//...
return c.name;
Sven Efftinge - itemis AG
14. Warum nicht einfach Felder benutzen?
public class Customer {
public String name;
}
... und ...
Customer c = new Customer();
c.name = “foobar”;
//...
return c.name;
Properties sind evtl. read-only
•
• getter bzw. setter enthalten Logik
Sven Efftinge - itemis AG
16. Mit “Properties”
public class Customer {
property String name;
... und ...
}
Customer c = new Customer();
c.name = “foobar”;
//...
return c.name;
• http://weblogs.java.net/blog/forax/archive/2007/01/property_reload.html
Sven Efftinge - itemis AG
17. Mit “Properties”
Beispiel für read-only Property mit speziellem Setter
public class Customer {
property String name set {
if (val!=null)
this.name = val;
};
}
• http://weblogs.java.net/blog/forax/archive/2007/01/property_reload.html
Sven Efftinge - itemis AG
19. Ein typisches Stück Javacode
public List<Person> withoutEmil(List<Person> list) {
List<Person> result = new ArrayList<Person>();
for(Person p : list) {
if (!p.getName().equals(“Emil”))
result.add(p);
}
return result;
}
Sven Efftinge - itemis AG
20. Type Inference
public List<Person> withoutEmil(List<Person> list) {
List<Person> result = new ArrayList<Person>();
for(Person p : list) {
if (!p.getName().equals(“Emil”))
result.add(p);
}
return result;
}
Typargument kann abgeleitet werden
Sven Efftinge - itemis AG
21. Type Inference
public List<Person> withoutEmil(List<Person> list) {
List<Person> result = new ArrayList();
for(Person p : list) {
if (!p.getName().equals(“Emil”))
result.add(p);
}
return result;
}
Variablentyp kann abgeleitet werden
Sven Efftinge - itemis AG
22. Type Inference
public List<Person> withoutEmil(List<Person> list) {
List<Person> result = new ArrayList();
for(p : list) {
if (!p.getName().equals(“Emil”))
result.add(p);
}
return result;
}
Rückgabetyp kann abgeleitet werden
Sven Efftinge - itemis AG
23. Type Inference
public withoutEmil(List<Person> list) {
List<Person> result = new ArrayList();
for(p : list) {
if (!p.getName().equals(“Emil”))
result.add(p);
}
return result;
}
Sven Efftinge - itemis AG
25. Type Inference in Java 7?
// Variablen Deklaration
Sven Efftinge - itemis AG
26. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
Sven Efftinge - itemis AG
27. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
Sven Efftinge - itemis AG
28. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
var families = createFamilies();
Sven Efftinge - itemis AG
29. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
var families = createFamilies();
// Ableiten aus dem Methodenkontext
Sven Efftinge - itemis AG
30. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
var families = createFamilies();
// Ableiten aus dem Methodenkontext
timeWaitsFor(new HashSet<>());
Sven Efftinge - itemis AG
31. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
var families = createFamilies();
// Ableiten aus dem Methodenkontext
timeWaitsFor(new HashSet<>());
// oder auch
Sven Efftinge - itemis AG
32. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
var families = createFamilies();
// Ableiten aus dem Methodenkontext
timeWaitsFor(new HashSet<>());
// oder auch
timeWaitsFor(Collections.emptySet());
Sven Efftinge - itemis AG
33. Type Inference in Java 7?
// Variablen Deklaration
Map<String, List<Person>> families = new HashMap<>();
var families = new HashMap<String, List<Person>>();
var families = createFamilies();
// Ableiten aus dem Methodenkontext
timeWaitsFor(new HashSet<>());
// oder auch
timeWaitsFor(Collections.emptySet());
// Mit Java 5 :
// timeWaitsFor(Collections.<Man>emptySet());
Sven Efftinge - itemis AG
40. Anwendungsfälle für Multiline Stringliterale
•Textuelle Testdaten
•Codegenerierung
•HTML/XML Erzeugung (Servlets, etc.)
Sven Efftinge - itemis AG
41. Anwendungsfälle für Multiline Stringliterale
•Textuelle Testdaten
•Codegenerierung
•HTML/XML Erzeugung (Servlets, etc.)
•Serienbriefe
Sven Efftinge - itemis AG
42. Anwendungsfälle für Multiline Stringliterale
•Textuelle Testdaten
•Codegenerierung
•HTML/XML Erzeugung (Servlets, etc.)
•Serienbriefe
•Nachrichten an den User (Logging, Error Messages)
Sven Efftinge - itemis AG
43. Multiline Stringliterale “selbstgebaut”
public void testConfig() throws Exception {
Configuration c = parse(
S(/*<config>
<bean class=quot;${Foobar.class.getName()}quot;>
<someProp value=quot;foobarquot;/>
</bean>
</config>*/));
assertEquals(quot;foobarquot;,c.getBeans().get(0).get(quot;somePropquot;));
}
author - company
44. Multiline Stringliterale “selbstgebaut”
public static String S() {
StackTraceElement element = new RuntimeException().getStackTrace()[1];
String name = element.getClassName().replace('.', '/') + quot;.javaquot;;
InputStream in = getClassLoader().getResourceAsStream(name);
String s = convertStreamToString(in, element.getLineNumber());
return s.substring(s.indexOf(quot;/*quot;)+2, s.indexOf(quot;*/quot;));
}
author - company
47. Java ist objektorientiert, oder?
Customer c = new Customer();
c.setName(quot;foobarquot;);
c.setId(4711);
Address address = new Address();
address.setStreet(quot;Schauenburgerstr. 116quot;);
address.setZip(quot;24118quot;);
address.setCity(quot;Kielquot;);
c.setAddress(address);
Order o1 = new Order();
o1.setArticleId(0815);
o1.setAmount(2);
c.addOrder(o1);
Sven Efftinge - itemis AG
48. Aktuell bevorzugter Weg
<Customer
name=quot;foobarquot;
id=”4711”>
<address>
<Address
street=”Schauenburgerstr. 116”
zip=”24118”
city=”Kiel”/>
</address>
<orders>
<Order
articleId=”0815”
amount=”2”/>
</orders>
</Customer>
Sven Efftinge - itemis AG
49. So könnte es aussehen...
Customer c = new Customer {
name = quot;foobarquot;;
id = 4711;
address = new Address {
street = quot;Schauenburgerstr. 116quot;;
zip = quot;24118quot;;
city = quot;Kielquot;;
};
addOrder(new Order {
articleId = 0815;
amount = 2;
});
};
Sven Efftinge - itemis AG
50. Initializer in anderen Sprachen
• Builder in Groovy
• Modelltransformationssprachen (ATL, QVT)
• In C# sieht’s so aus: Person person = new Person {
FirstName = quot;Scottquot;,
LastName = quot;Guthriequot;,
Age = 32,
Address = new Address {
Street = quot;One Microsoft Wayquot;,
City = quot;Redmondquot;,
State = quot;WAquot;,
Zip = 98052
}
};
Sven Efftinge - itemis AG
51. Übrigens so geht es auch schon heute...
Customer c = new Customer() {{
name = quot;foobarquot;;
id = 4711;
address = new Address() {{
street = quot;Schauenburgerstr. 116quot;;
zip = quot;24118quot;;
city = quot;Kielquot;;
}};
addOrder(new Order() {{
articleId = 0815;
amount = 2;
}});
}};
Sven Efftinge - itemis AG
52. Übrigens so geht es auch schon heute...
Customer c = new Customer() {{
name = quot;foobarquot;;
id = 4711;
address = new Address() {{
street = quot;Schauenburgerstr. 116quot;;
zip = quot;24118quot;;
city = quot;Kielquot;;
}};
addOrder(new Order() {{
articleId = 0815;
amount = 2;
}});
}};
Kombination aus Anonymen Klassen und
den “alten” non-static initializers
Sven Efftinge - itemis AG
55. Collections sind allgegenwärtig
Map<String,Person> personByName = new HashMap<String,Person>();
personByName.put(heinrich.getName(), heinrich);
personByName.put(maria.getName(), maria);
personByName.put(horst.getName(), horst);
Sven Efftinge - itemis AG
56. Collections sind allgegenwärtig
Map<String,Person> personByName = new HashMap<String,Person>();
personByName.put(heinrich.getName(), heinrich);
personByName.put(maria.getName(), maria);
personByName.put(horst.getName(), horst);
Map<String,Person> personByName = new HashMap<String,Person>() {
heinrich.getName() => heinrich,
maria.getName() => maria,
horst.getName()
=> horst
};
Sven Efftinge - itemis AG
57. Collections sind allgegenwärtig
Map<String,Person> personByName = new HashMap<String,Person>();
personByName.put(heinrich.getName(), heinrich);
personByName.put(maria.getName(), maria);
personByName.put(horst.getName(), horst);
// mit Typinferenz könnte es so aussehen
var personByName = new HashMap<>() {
heinrich.getName() => heinrich,
maria.getName() => maria,
horst.getName()
=> horst
};
Sven Efftinge - itemis AG
58. Collectionliteral in C#
Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
{
{ 111, new StudentName {FirstName=quot;Sachinquot;, LastName=quot;Karnikquot;, ID=211}},
{ 112, new StudentName {FirstName=quot;Dinaquot;, LastName=quot;Salimzianovaquot;, ID=317}},
{ 113, new StudentName {FirstName=quot;Andyquot;, LastName=quot;Ruthquot;, ID=198}}
};
Sven Efftinge - itemis AG
59. Collectionliteral in C#
Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
{
{ 111, new StudentName {FirstName=quot;Sachinquot;, LastName=quot;Karnikquot;, ID=211}},
{ 112, new StudentName {FirstName=quot;Dinaquot;, LastName=quot;Salimzianovaquot;, ID=317}},
{ 113, new StudentName {FirstName=quot;Andyquot;, LastName=quot;Ruthquot;, ID=198}}
};
In Kombination mit den zuvor genannten
Erweiterungen könnte es in Java so aussehen:
var students = new HashMap<>() {
111 => new StudentName {firstName=quot;Sachinquot;, lastName=quot;Karnikquot;, id=211},
112 => new StudentName {firstName=quot;Dinaquot;, lastName=quot;Salimzianovaquot;, id=317},
113 => new StudentName {firstName=quot;Andyquot;, lastName=quot;Ruthquot;, id=198}
};
Sven Efftinge - itemis AG
60. Collection-Literale in Java
import static java.util.Arrays.asList;
class Foo {
List<String> createList() {
return asList(“a”,”b”,”c”);
}
}
Sven Efftinge - itemis AG
61. Collection-Literale in Java
import static com.google.common.collect.Maps.*;
class Foo {
List<String, int> createMap() {
return immutableMap(“a”,2,”c”,3);
}
}
Sven Efftinge - itemis AG
62. Collection-Literale in Java
Eine Proposal für eine Spracherweiterung
gibt es z.B. unter
http://jroller.com/scolebourne/entry/java_7_list_and_map
Sven Efftinge - itemis AG
64. Anonyme Datenstrukturen erzeugen
var students = new Map<>()
{
111 => new {firstName=quot;Sachinquot;, lastName=quot;Karnikquot;, ID=211},
112 => new {firstName=quot;Dinaquot;, lastName=quot;Salimzianovaquot;, ID=317},
113 => new {firstName=quot;Andyquot;, lastName=quot;Ruthquot;, ID=1989}
};
Sven Efftinge - itemis AG
65. Anonyme Datenstrukturen erzeugen
var students = new Map<>()
{
111 => new {firstName=quot;Sachinquot;, lastName=quot;Karnikquot;, ID=211},
112 => new {firstName=quot;Dinaquot;, lastName=quot;Salimzianovaquot;, ID=317},
113 => new {firstName=quot;Andyquot;, lastName=quot;Ruthquot;, ID=1989}
};
Map<Int, AnonymousType<firstName::String,lastName::String,ID::Int>>
Typinferenz ist unbedingt erforderlich
Sven Efftinge - itemis AG
73. Closure: Anonyme Funktion
• Ein Literal für Funktionen
• Speichert den Umgebenden Kontext und greift bei der Ausführung darauf zu
Sven Efftinge - itemis AG
74. Closure: Anonyme Funktion
• Ein Literal für Funktionen
• Speichert den Umgebenden Kontext und greift bei der Ausführung darauf zu
{Person p=>p.getName().equals(“foo”)}
Sven Efftinge - itemis AG
75. Closure: Anonyme Funktion
• Ein Literal für Funktionen
• Speichert den Umgebenden Kontext und greift bei der Ausführung darauf zu
{Person p=>p.getName().equals(“foo”)}
Declared
Parameters
Sven Efftinge - itemis AG
76. Closure: Anonyme Funktion
• Ein Literal für Funktionen
• Speichert den Umgebenden Kontext und greift bei der Ausführung darauf zu
{Person p=>p.getName().equals(“foo”)}
Declared Block or expression
Parameters to be executed
Sven Efftinge - itemis AG
78. Typische Higher-Order Functions auf Mengen
• List<T> select({T => boolean} func)
Gibt eine neue Liste, die nur die Werte enthält, für die die Funktion
‘true’ zurückgegeben hat.
Sven Efftinge - itemis AG
79. Typische Higher-Order Functions auf Mengen
• List<T> select({T => boolean} func)
Gibt eine neue Liste, die nur die Werte enthält, für die die Funktion
‘true’ zurückgegeben hat.
• List<R> collect({T => R} func)
Sammelt die Rückgabewerte und gibt sie als Liste zurück
Sven Efftinge - itemis AG
80. Typische Higher-Order Functions auf Mengen
• List<T> select({T => boolean} func)
Gibt eine neue Liste, die nur die Werte enthält, für die die Funktion
‘true’ zurückgegeben hat.
• List<R> collect({T => R} func)
Sammelt die Rückgabewerte und gibt sie als Liste zurück
• List<T> sort({T,T => int} func)
Sortiert die Liste anhand einer Vergleichsfunktion (Comparator)
Sven Efftinge - itemis AG
81. Typische Higher-Order Functions auf Mengen
• List<T> select({T => boolean} func)
Gibt eine neue Liste, die nur die Werte enthält, für die die Funktion
‘true’ zurückgegeben hat.
• List<R> collect({T => R} func)
Sammelt die Rückgabewerte und gibt sie als Liste zurück
• List<T> sort({T,T => int} func)
Sortiert die Liste anhand einer Vergleichsfunktion (Comparator)
• boolean exists({T => boolean} func)
Prüft, ob die Funktion für mindestens ein Element ‘true’ zurück gibt
Sven Efftinge - itemis AG
87. Polymorphismus in Java
class Foo {
void doStuff() {
System.out.println(“foo”); Foo
}
}
class SpecialFoo extends Foo {
void doStuff() {
System.out.println(“specialfoo”);
SpecialFoo
}
}
Sven Efftinge - itemis AG
88. Polymorphismus in Java
new SpecialFoo().doStuff();
((Foo) new SpecialFoo()).doStuff();
Foo
class Foo {
void doStuff() {
System.out.println(“foo”);
} SpecialFoo
}
class SpecialFoo extends Foo {
void doStuff() {
System.out.println(“specialfoo”);
}
}
Sven Efftinge - itemis AG
89. Polymorphismus in Java
new SpecialFoo().doStuff();
((Foo) new SpecialFoo()).doStuff();
Foo
output:
specialfoo
specialfoo
SpecialFoo
Sven Efftinge - itemis AG
90. Polymorphismus in Java (2)
class Foo {
}
class SpecialFoo extends Foo {
}
static void doStuff(SpecialFoo arg) {
System.out.println(“specialfoo”);
}
static void doStuff(Foo arg) {
System.out.println(“foo”);
}
Sven Efftinge - itemis AG
91. Polymorphismus in Java (2)
doStuff(new SpecialFoo());
doStuff((Foo) new SpecialFoo());
class Foo {
}
class SpecialFoo extends Foo {
}
static void doStuff(SpecialFoo arg) {
System.out.println(“specialfoo”);
}
static void doStuff(Foo arg) {
System.out.println(“foo”);
}
Sven Efftinge - itemis AG
92. Polymorphismus in Java (2)
doStuff(new SpecialFoo());
doStuff((Foo) new SpecialFoo());
output:
specialfoo
foo
Sven Efftinge - itemis AG
93. Mit Dynamic Dispatch in Java
doStuff(new SpecialFoo());
doStuff((Foo) new SpecialFoo();
output:
specialfoo
specialfoo
Sven Efftinge - itemis AG
94. Dynamic Dispatch in Java (2)
class Foo {
//....
public boolean equals(Object arg) {
if (arg instanceof Foo) {
Foo arg1 = (Foo) arg;
return name.equals(arg.name);
}
return false;
}
}
Sven Efftinge - itemis AG
95. Dynamic Dispatch in Java (2)
class Foo {
//...
public boolean equals(Foo arg) {
return name.equals(arg.name);
}
}
Sven Efftinge - itemis AG
97. Multimethod / Dynamic Dispatch
• Non-Invasive und polymorphe Erweiterung von Typhierarchien
Sven Efftinge - itemis AG
98. Multimethod / Dynamic Dispatch
• Non-Invasive und polymorphe Erweiterung von Typhierarchien
• Ersetzt das Visitor-Pattern
Sven Efftinge - itemis AG
99. Multimethod / Dynamic Dispatch
• Non-Invasive und polymorphe Erweiterung von Typhierarchien
• Ersetzt das Visitor-Pattern
• Ersetzt viele ‘instanceof’ Abfragen
Sven Efftinge - itemis AG
100. Multimethod / Dynamic Dispatch
• Non-Invasive und polymorphe Erweiterung von Typhierarchien
• Ersetzt das Visitor-Pattern
• Ersetzt viele ‘instanceof’ Abfragen
• Auch sehr nett in Kombination mit “Extension Methods”
foo.staticMethod() statt staticMethod(foo)
Sven Efftinge - itemis AG
113. Statische Typisierung
•Grundsätzlich sehr nützlich (Feedback!)
•Die Werkzeugunterstützung basiert darauf
•Kein Widerspruch zu
•Kurzen Turn-Arounds
Sven Efftinge - itemis AG
114. Statische Typisierung
•Grundsätzlich sehr nützlich (Feedback!)
•Die Werkzeugunterstützung basiert darauf
•Kein Widerspruch zu
•Kurzen Turn-Arounds
•Interaktiver Entwicklung
Sven Efftinge - itemis AG
119. Statische Typisierung
•Kein Ersatz für Unittests
•Erhöhte Komplexität
•statische vs. dynamische Typen
•Generics
Sven Efftinge - itemis AG
120. Statische Typisierung
•Kein Ersatz für Unittests
•Erhöhte Komplexität
•statische vs. dynamische Typen
•Generics
•oft umständliche, generische Programmierung via
Reflection
Sven Efftinge - itemis AG
122. Warum nicht beides?
• Die allermeisten Codezeilen können sinnvoll statisch getypt werden
Sven Efftinge - itemis AG
123. Warum nicht beides?
• Die allermeisten Codezeilen können sinnvoll statisch getypt werden
• Dynamische Programmierung eher in der Framework-Entwicklung
Sven Efftinge - itemis AG
124. Warum nicht beides?
• Die allermeisten Codezeilen können sinnvoll statisch getypt werden
• Dynamische Programmierung eher in der Framework-Entwicklung
• z.B. durch explizite CompilerEscapes : foo.~unkownMethod()
Sven Efftinge - itemis AG
125. Warum nicht beides?
• Die allermeisten Codezeilen können sinnvoll statisch getypt werden
• Dynamische Programmierung eher in der Framework-Entwicklung
• z.B. durch explizite CompilerEscapes : foo.~unkownMethod()
• Casts nicht im ByteCode
Sven Efftinge - itemis AG
126. Warum nicht beides?
• Die allermeisten Codezeilen können sinnvoll statisch getypt werden
• Dynamische Programmierung eher in der Framework-Entwicklung
• z.B. durch explizite CompilerEscapes : foo.~unkownMethod()
• Casts nicht im ByteCode
• methodMissing() Methode auf java.lang.Object
Sven Efftinge - itemis AG
127. Warum nicht beides?
• Die allermeisten Codezeilen können sinnvoll statisch getypt werden
• Dynamische Programmierung eher in der Framework-Entwicklung
• z.B. durch explizite CompilerEscapes : foo.~unkownMethod()
• Casts nicht im ByteCode
• methodMissing() Methode auf java.lang.Object
• Zur Laufzeit Methoden und Klassen hinzufügen
Sven Efftinge - itemis AG