Download presentation
Presentation is loading. Please wait.
Published byEzra Hoover Modified over 8 years ago
1
What's Wrong With Java? A Critical Look from Other Languages Aaron Digulla Globus SSC 560
2
2 AGENDA > About you and me > Lists in Java, Python and Groovy > ORM in three languages > Statistics > Conclusions
3
About the Speaker > Develops software for 20 years > Wrote complex programs in over 20 different languages: – Java, Python, Groovy – Perl, C, Shell (Korn Shell/Bash, tcl/tk) – SQL (Oracle, Sybase, MySQL, DB2) – Assembler (6502, 68000, x86) – BASIC (various)
4
Who, me? > We're not stupid > When someone comes around with a new idea, we are easily offended > Filter for bad ideas > Makes it hard to adopt new ideas
5
Java, anyone? Puzzle 6: Multicase public class Multicast { public static void main(String[] args) { System.out.println ((int) (char) (byte) - 1); } Puzzle 16: Line Printer public class LinePrinter { public static void main(String[] args) { // Note: \u000A is linefeed (LF) char c = 0x000A; System.out.println (c); } Source: Java Puzzlers, p.15 and p.35
6
The Good, Bad and Ugly > Sorting lists, Java Style import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortingLists { public static void demo1 () { List list = new ArrayList (); list.add ("a"); list.add ("c"); list.add ("b"); Collections.sort (list); System.out.println (list); } import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class SortingLists { public static void demo1 () { List list = new ArrayList (); list.add ("a"); list.add ("c"); list.add ("b"); Collections.sort (list); System.out.println (list); }
7
Sorting in Python / Groovy > Python: > Groovy: def demo1 (): list = [ 'a', "c", """b""", ] list.sort () print list def demo1 (): list = [ 'a', "c", """b""", ] list.sort () print list class GsortingLists { static void demo1 () { def list = [ 'a', "c", """b""", ] list.sort () println list } class GsortingLists { static void demo1 () { def list = [ 'a', "c", """b""", ] list.sort () println list }
8
public static void demo2 () { List list = new ArrayList (); list.add (new NamedObject ("a")); list.add (new NamedObject ("c")); list.add (new NamedObject (null)); list.add (null); list.add (new NamedObject ("B")); Collections.sort (list, new Comparator () { public int compare (NamedObject o1, NamedObject o2) { if (o1 == null) return (o2 == null) ? 0 : -1; } else if (o2 == null) { return 1; } if (o1.getName() == null) { return (o2.getName() == null) ? 0 : -1; } else if (o2.getName() == null) { return 1; } return o1.getName().compareToIgnoreCase ( o2.getName()); } }); System.out.println (list); } public static void demo2 () { List list = new ArrayList (); list.add (new NamedObject ("a")); list.add (new NamedObject ("c")); list.add (new NamedObject (null)); list.add (null); list.add (new NamedObject ("B")); Collections.sort (list, new Comparator () { public int compare (NamedObject o1, NamedObject o2) { if (o1 == null) return (o2 == null) ? 0 : -1; } else if (o2 == null) { return 1; } if (o1.getName() == null) { return (o2.getName() == null) ? 0 : -1; } else if (o2.getName() == null) { return 1; } return o1.getName().compareToIgnoreCase ( o2.getName()); } }); System.out.println (list); } Complex Lists: Java public class NamedObject { private String name; public NamedObject () { // When using setters } public NamedObject (String name) { this.name = name; } public String getName () { return name; } public void setName (String name) { this.name = name; } public String toString () { return "Name="+name; } public class NamedObject { private String name; public NamedObject () { // When using setters } public NamedObject (String name) { this.name = name; } public String getName () { return name; } public void setName (String name) { this.name = name; } public String toString () { return "Name="+name; }
9
Complex List: Python class NamedObject: def __init__ (self, name=None): self.name = name def __repr__ (self): return "Name=%s" % self.name def demo2 (): list = [ NamedObject ('a'), NamedObject ('c'), NamedObject (), None, NamedObject ('B'), ] def getName (o): if o.name is None: return None return o.name.lower () def noCmp (x,y): if x is None or y is None: return cmp (x, y) return cmp (getName (x), getName (y)) list.sort (noCmp) print list class NamedObject: def __init__ (self, name=None): self.name = name def __repr__ (self): return "Name=%s" % self.name def demo2 (): list = [ NamedObject ('a'), NamedObject ('c'), NamedObject (), None, NamedObject ('B'), ] def getName (o): if o.name is None: return None return o.name.lower () def noCmp (x,y): if x is None or y is None: return cmp (x, y) return cmp (getName (x), getName (y)) list.sort (noCmp) print list
10
Complex List: Groovy class GNamedObject { String name; String toString () { return "Name=${name}" } class GSortingLists { //... static int noCmp (x, y) { if (x == null) { return y == null ? 0 : -1; } else if (y == null) { return 1; } class GNamedObject { String name; String toString () { return "Name=${name}" } class GSortingLists { //... static int noCmp (x, y) { if (x == null) { return y == null ? 0 : -1; } else if (y == null) { return 1; } static void demo2 () { def list = [ new GNamedObject (name:'a'), new GNamedObject (name:'c'), new GNamedObject (name:null), null, new GNamedObject (name:'B'), ] list.sort () { x,y -> if (x == null || y == null) return noCmp (x, y) x = x.name y = y.name if (x == null || y == null) return noCmp (x, y) return x.compareToIgnoreCase (y) } println list } static void demo2 () { def list = [ new GNamedObject (name:'a'), new GNamedObject (name:'c'), new GNamedObject (name:null), null, new GNamedObject (name:'B'), ] list.sort () { x,y -> if (x == null || y == null) return noCmp (x, y) x = x.name y = y.name if (x == null || y == null) return noCmp (x, y) return x.compareToIgnoreCase (y) } println list }
11
Complex List: Groovy (2) class GnamedObject { String name; String toString () { return "Name=${name}" } class GsortingLists { //... static void demo2b () { def list = [ new GNamedObject (name:'a'), new GNamedObject (name:'c'), new GNamedObject (name:null), null, new GNamedObject (name:'B'), ] list.sort () { def n = it?.name?.toLowerCase () return (n == null) ? '' : n } println list } class GnamedObject { String name; String toString () { return "Name=${name}" } class GsortingLists { //... static void demo2b () { def list = [ new GNamedObject (name:'a'), new GNamedObject (name:'c'), new GNamedObject (name:null), null, new GNamedObject (name:'B'), ] list.sort () { def n = it?.name?.toLowerCase () return (n == null) ? '' : n } println list }
12
Conclusions (1) > Common tasks become more simple as languages evolve > Languages die (like dinosaurs) > Java, Jython, Groovy and JRuby run on the same VM but offer different ways to solve the same problem
13
ORM Keywor d name : String type : int Knowledg e mimeType : String content : String Relatio n name 1..* keywords 0..* name 1..* from 0..* to 0..* parent 0..*
14
ORM: Java > ORM in Java is impossible > You have to use a mapper, learn a second technology > Java has no closures, so transaction handling is complex > Exception handling is complex > For many cases, you can avoid SQL but not for all, so you still have to learn it > Java 5 adds annotations which help
15
ORM: Python from turbogears.database import PackageHub from sqlobject import * import types hub = PackageHub("sensei") __connection__ = hub class Keyword(SQLObject): KNOWLEDGE = 1 KEYWORD = 2 RELATION = 3 type = IntCol() name = UnicodeCol(length=256) lc_name = UnicodeCol(length=256) nameIndex = DatabaseIndex('lc_name', 'type', unique=True) relations = MultipleJoin('Relation', joinColumn='name') knowledge = RelatedJoin('Knowledge') def createKeyword(name, type=KeywordType.KEYWORD): return Keyword(type=type, name=name, lc_name=name.lower()) def keywordByName(name, type=None): if type is None: return Keyword.select(Keyword.q.lc_name.startswith (name.lower())) return Keyword.select(AND ( Keyword.q.lc_name.startswith (name.lower()), Keyword.q.type == type)) def keywordByType(type): return Keyword.select(Keyword.q.type == type) from turbogears.database import PackageHub from sqlobject import * import types hub = PackageHub("sensei") __connection__ = hub class Keyword(SQLObject): KNOWLEDGE = 1 KEYWORD = 2 RELATION = 3 type = IntCol() name = UnicodeCol(length=256) lc_name = UnicodeCol(length=256) nameIndex = DatabaseIndex('lc_name', 'type', unique=True) relations = MultipleJoin('Relation', joinColumn='name') knowledge = RelatedJoin('Knowledge') def createKeyword(name, type=KeywordType.KEYWORD): return Keyword(type=type, name=name, lc_name=name.lower()) def keywordByName(name, type=None): if type is None: return Keyword.select(Keyword.q.lc_name.startswith (name.lower())) return Keyword.select(AND ( Keyword.q.lc_name.startswith (name.lower()), Keyword.q.type == type)) def keywordByType(type): return Keyword.select(Keyword.q.type == type)
16
ORM: Grails class Keyword { final static int KNOWLEDGE = 1 final static int KEYWORD = 2 final static int RELATION = 3 int type String name String lcName void setName (String name) { this.name = name this.lcName = name.toLowerCase() } class Knowledge { Keyword name String mimeType String text Knowledge parent List children static optionals = [ "parent" ] static hasMany = [keywords:Keyword, children:Knowledge] } class Keyword { final static int KNOWLEDGE = 1 final static int KEYWORD = 2 final static int RELATION = 3 int type String name String lcName void setName (String name) { this.name = name this.lcName = name.toLowerCase() } class Knowledge { Keyword name String mimeType String text Knowledge parent List children static optionals = [ "parent" ] static hasMany = [keywords:Keyword, children:Knowledge] }
17
ORM: Statistics > Java 4, H 3.1: 2 Weeks, 6 KLOC, some hair pulling > Java 5, H 3.2: 1 Week, 5.5 KLOC, fair > TurboGears: 3 Days, 1 KLOC, nice > Grails: 1 Week, < 1 KLOC, nice
18
Conclusions (2) > Simple problems like CRUD need a lot of code in Java > More and more frameworks “solve” problems in XML rather than Java > The solution to each single problem is spread over several files > It becomes harder and harder merely to follow the current developments (Spring, AOP, Hibernate,...)
19
Now what? > Many common problems can be solved much more effectively in other languages > Python, Groovy and Ruby also run on the Java VM and integrate nicely with existing code > Write the majority of the code in the language which fits the problem > Sometimes, it is faster to rewrite the old code using the new technology
20
Further Reading “Beyond Java”, Bruce A. Tate, ISBN-13: 978-0596100940 “Java Puzzlers”, Joshua Bloch, ISBN-13: 978-0321336781
21
Aaron Digullawww.globus.ch Globus SSCAaron.Digulla@globus.ch
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.