Presentation is loading. Please wait.

Presentation is loading. Please wait.

Effective Java – General Programming Global Server Dept. Hu Qiongkai

Similar presentations


Presentation on theme: "Effective Java – General Programming Global Server Dept. Hu Qiongkai"— Presentation transcript:

1 Effective Java – General Programming Global Server Dept. Hu Qiongkai qkhu@telenav.cn

2 Content  Minimize the scope of local variables  Beware performance of string concatenation  Prefer for-each loops to traditional for loops  Refer to objects by their interfaces  Avoid float/double if exact answers required  Prefer interfaces to reflection  Prefer primitive types to boxed primitives  Avoid strings where other types are more appropriate  Other practical principals

3 Minimize the scope of local variables  Before use a variable  declare variable  variable initialization  Variable scope  Inside a block try { String s = “”; } catch (Exception e){}  in for statement // Preferred idiom for iterating over a collection since JDK1.5 for (Element e : c) { doSomething(e); } // No for-each loop or generics before release 1.5 for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething((Element) i.next()); }  outside a block String s = null; try { s = “”; } catch (Exception e){}

4 Minimize the scope of local variables(2)  cut-and-paste error Iterator i = c.iterator(); while (i.hasNext()) { doSomething(i.next()); }... Iterator i2 = c2.iterator(); while (i.hasNext()) { // runtime BUG! doSomethingElse(i2.next()); }  Better practice  Time to declare variable: at where it is first used  Initialization tip: in a try/catch block, if variable needs be used outside block, should initilize it outside try/catch  prefer ‘for’ loops to ‘while’ loops  keep methods small and focused for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething(i.next()); }... // Compile-time error - cannot find symbol i for (Iterator i2 = c2.iterator(); i.hasNext(); ) { doSomething(i2.next()); }

5 Beware performance of string concatenation  Simple concatenation with ‘+’ public String concat4(String s1, String s2, String s3, String s4) { return s1 + s2 + s3 + s4; } # Before JDK5  Using ‘+’ repeatedly to concatenate n strings requires time quadratic in n(n 2 ).  String is immutable, for concatenation with ‘+’, needs characters copied and a new result String object created. # Since JDK5  auto optimized by compiled into using StringBuilder.append().  compiled sample: String ss = (new StringBuilder("ok")).append(s).append("xyz").append(5).toString();

6 Beware performance of string concatenation(2)  Complex concatenation with ‘+’  what if concatenation in a ‘for’ statement? Random rand = new Random(); for (int i = 0; i < 10; i++) { s = s + rand.nextInt(1000) + " "; } # compiled sample: StringBuilder result = new StringBuilder(); for(int i = 0; i < 10; i++) { s = (new StringBuilder(String.valueOf(s))).append(rand.nextInt(1000)).append(" ").toString(); } # Tip  new a StringBuilder Object for each item in ‘for’ statement

7 Beware performance of string concatenation(3)  Better performance: use StringBuilder/StringBuffer instead  java.lang.StringBuilder mutable sequence of characters no guarantee for thread safe  java.lang.StringBuffer thread-safe, mutable sequence of characters Class Hierarchy

8 Prefer for-each loops to traditional for loops  traditional for loops // No longer the preferred idiom to iterate over a collection! for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething((Element) i.next()); // (No generics before 1.5) } // No longer the preferred idiom to iterate over an array! for (int i = 0; i < a.length; i++) { doSomething(a[i]); }  for-each loops // The preferred idiom for iterating over collections and arrays for (Element e : elements) { doSomething(e); }  advantages by using for-each  code clarity  no performance penalty, even slight better during loop an array, only computes index once  bug prevention?

9 Prefer for-each loops to traditional for loops(2)  Can you spot the bug? enum Suit { CLUB, DIAMOND, HEART, SPADE } enum Rank { ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING }... Collection suits = Arrays.asList(Suit.values()); Collection ranks = Arrays.asList(Rank.values()); List deck = new ArrayList (); for (Iterator i = suits.iterator(); i.hasNext(); ) for (Iterator j = ranks.iterator(); j.hasNext(); ) deck.add(new Card(i.next(), j.next()));  Solutions to prevent the bug  fix it in traditional way // Fixed, but ugly - you can do better! for (Iterator i = suits.iterator(); i.hasNext(); ) { Suit suit = i.next(); for (Iterator j = ranks.iterator(); j.hasNext(); ) deck.add(new Card(suit, j.next())); }  use for-each instead // Preferred idiom for nested iteration for (Suit suit : suits) for (Rank rank : ranks) deck.add(new Card(suit, rank));

10 Refer to objects by their interfaces  Interface oriented programming methodology  big advantage: much more flexible  sample case // Bad - uses class as type! Vector subscribers = new Vector (); // Good - uses interface as type List subscribers = new Vector (); // We can change subscribers to other List types easily List subscribers = new ArrayList ();  practical case in spring

11 Avoid float/double if exact answers required  Problems System.out.println(1.03 -.42); # output 0.6100000000000001  Why it happens  binary floating-point arithmetic  float/double types are particularly illsuited for monetary calculations  Solutions to achieve exact computation  using java.math.BigDecimal BigDecimal bigDecimal = new BigDecimal("1.03"); System.out.println(bigDecimal.subtract(new BigDecimal(".42"))); # Tips -exact computation -performance impacted  using primitive arithmetic type: int or long -high performance -decimal point has to be handled manually

12 Prefer interfaces to reflection  What reflection can do Given a Class object, you can obtain Constructor, Method, and Field instances representing the constructors, methods, and fields of the class represented by the Class instance.  case study  initialize class instance via reflection Class cl = null; try { cl = Class.forName(args[0]); // Instantiate the class Set s = null; s = (Set ) cl.newInstance(); } catch(Exception e) {}  access class method/field via reflection Field f = cl.getClass().getDeclaredField(“f1"); f.setAccessible(true); Method m = f.getType().getDeclaredMethod(“f1m1", new Class[0]); m.setAccessible(true); m.invoke(cl, new Object[0]);

13 Prefer interfaces to reflection  cost on using reflection  no compile-time type checking  code clumsy and verbose  Performance suffers  When to use reflection  in runtime, better to use class instance normal access, unless necessary  base framework Spring Struts OSGI  dynamic class loading management

14 Prefer primitive types to boxed primitives  auto-boxing and auto-unboxing  since JDK1.5  sample  case study // Broken comparator - can you spot the flaw? Comparator naturalOrder = new Comparator () { public int compare(Integer first, Integer second) { return first < second ? -1 : (first == second ? 0 : 1); } }; Primitive typeReference type intjava.lang.Integer doublejava.lang.Double booleanjava.lang.Boolean

15 Prefer primitive types to boxed primitives(2)  fix the bug Comparator naturalOrder = new Comparator () { public int compare(Integer first, Integer second) { int f = first; // Auto-unboxing int s = second; // Auto-unboxing return f < s ? -1 : (f == s ? 0 : 1); // No unboxing } };  when you mix primitives and boxed primitives in a single operation, the boxed primitive is auto-unboxing public class Unbelievable { static Integer i; public static void main(String[] args) { if (i == 42) throws NullPointerException for Integer auto-unboxing System.out.println("Unbelievable"); }

16 Prefer primitive types to boxed primitives(3)  performance suffers during auto-boxing/unboxing // Hideously slow program! Can you spot the object creation? public static void main(String[] args) { Long sum = 0L; for (long i = 0; i < Integer.MAX_VALUE; i++) { sum += i; } System.out.println(sum); }  more practice tips  primitive types are simpler and faster  auto-boxing reduces the verbosity, but not the danger, of using boxed primitives  use boxed primitives as type parameter in in parameterized types // sample List l = new ArrayList (); ThreadLocal tl = new ThreadLocal ();

17 Avoid strings where other types are more appropriate  Strings are designed to represent text  poor substitutes for capabilities // Broken - inappropriate use of string as capability! public class ThreadLocal1 { private ThreadLocal1() { } // Non-instantiable // Sets the current thread's value for the named variable. public static void set(String key, Object value); // Returns the current thread's value for the named variable. public static Object get(String key); }  poor substitutes for enum types, hard to maintain public static enum UserRole { Admin, PM, BusinessOwner, Marketing, Finance, Legal }  poor substitutes for not text value types  Other

18 Other practical principles  Know and use the standard JDK libraries  By using a standard library, you take advantage of the knowledge of the experts who wrote it and the experience of those who used it before you.  java.lang, java.util, java.io  Use native methods judiciously  JNI: Java Native Interface  Platform dependent, less portable  Not safe, need anually memory control  Has a fixed cost associated with going into/out of native code  JVM gets faster, rarely advisable to use native method for performance gain  Optimize judiciously  write good program, architecture first, performance follows  avoid design decisions that limit performance  use profiling tools to determine performance optimization focus  Adhere to generally accepted naming conventions

19


Download ppt "Effective Java – General Programming Global Server Dept. Hu Qiongkai"

Similar presentations


Ads by Google