Date post: | 04-Jun-2018 |
Category: |
Documents |
Upload: | abhisek-mukherjee |
View: | 225 times |
Download: | 0 times |
of 39
8/13/2019 Programming Best Practices in Java
1/39
2010 IBM Corporation
Programming Best Practices in JavaTM
Shirish Kuncolienkar
07 November 2012
8/13/2019 Programming Best Practices in Java
2/39
2010 IBM Corporation
Please NoteIBM's statements regarding its plans, directions, and intent are subject to change
or withdrawal at IBM's sole discretion.
Information regarding potential future products is intended to outline our generalproduct direction and it should not be relied on in making a purchasing decision.
The information mentioned regarding potential future products is not acommitment, promise, or legal obligation to deliver any material, code orfunctionality. Information about potential future products may not be incorporatedinto any contract. The development, release, and timing of any future features or
functionality described for our products remains at our sole discretion.
Performance is based on measurements and projections using standard IBMbenchmarks in a controlled environment. The actual throughput or performancethat any user will experience will vary depending upon many factors, including
considerations such as the amount of multiprogramming in the user's job stream,the I/O configuration, the storage configuration, and the workload processed.
Therefore, no assurance can be given that an individual user will achieve resultssimilar to those stated here.
8/13/2019 Programming Best Practices in Java
3/39
8/13/2019 Programming Best Practices in Java
4/39
2010 IBM Corporation
Agenda
Creating and destroying objects
Common methods
Classes and Interfaces
Methods
General programming
Exceptions
Threads
8/13/2019 Programming Best Practices in Java
5/39
2010 IBM Corporation
Creating and destroying objects
8/13/2019 Programming Best Practices in Java
6/39
2010 IBM Corporation
#1 Prefer static factory methods to constructors
public static Boolean valueOf(boolean b) {return (b ? Boolean.TRUE : Boolean.FALSE);
}
Meaningful names unlike constructor
Can have two methods with same signature
Allows re-use of existing objects
Can return objects of a subtype
8/13/2019 Programming Best Practices in Java
7/39
2010 IBM Corporation
Example of static factory methods
public abstract class Pen {
public static final INK_PEN = InkPen;
public static final FELT_PEN = FeltPen;
Pen() {}
public static Pen createPen(String type){
try {
Pen p = (Pen)Class.forname(type).newInstance();
return p;
} catch (Exception ex) {
return null;
}
}
public abstract void draw( );}
class FeltPen extends Pen {
FeltPen() { }
public voiddraw( ) {
}
}
class InkPen extends Pen {
InkPen() { }
public voiddraw( ) {
}
}
8/13/2019 Programming Best Practices in Java
8/39
2010 IBM Corporation
#2 private constructors
Restricts construction only from within the class
Class cannot be extended
Enforce non-instantiability
When should I declare the constructor private?
Singletons
One and only one valid object instance is createdE.g. Standard output stream
Utility classes
Grouping of static fields and methodsSort of a abstract final class
E.g. java.lang.System
8/13/2019 Programming Best Practices in Java
9/39
2010 IBM Corporation
#3 reuse objects
Faster and stylish
Ideal candidates
Immutable objectsObject constant in the application lifetime.
Costlier to construct (threads, connections, configuration)
public abstract class Pen {
public static Pen createPen(String type){
return getCachedPen(type);
}
public static Pen getCachedPen(String type) {
Pen pen = cache.get(type);
if( pen == null) {
try {
pen = (Pen)(Class.forname(type).newInstance());
cache.put(type,pen);
} catch (Exception ex) {
}
}
return pen;
}
private static HashMap cache = new HashMap();
}
8/13/2019 Programming Best Practices in Java
10/39
2010 IBM Corporation
#4 Eliminate obsolete objects
Increased heap occupancy and frequent garbage collections
Typical placesArray based stack implementationsCaches (HashMap, Hashtable)
Nullify references where obvious
Remove cached objects which are no longer required
Periodic cleanup. (WeakHashMap)
Do not overdoEvery object has a root objectNullifying the root should make its children garbage
collectible
8/13/2019 Programming Best Practices in Java
11/39
2010 IBM Corporation
#5 use finalizers cautiously
They are not destructorsUse try-finally syntax for closing system resourcesNot guaranteed to run in predictable manner -Do not do
anything time critical in finalizers
Dangerous Any uncaught exceptions will be ignored
terminating finlizationTry explicit termination methods like close(), destroy(),
cancel()
8/13/2019 Programming Best Practices in Java
12/39
2010 IBM Corporation
Common methods
8/13/2019 Programming Best Practices in Java
13/39
2010 IBM Corporation
#6 obey equals() contract
Do not override ifEach instance in inherently uniqueDo not care if the class fails logical equality testSuper class implementation is good enoughClass is private or package-privateYou are sure that equals method will never get called
Override ifYou need to check the logical equalityClass instances will be used as a key in mapsClass instances will be inserted into set
The contractReflexive x.equals(x) returns trueSymmetric if x.equals(y) = true then y.equals(x)Transitive if x.equals(y) = true and y.equals(z) = true thenx.equals(z) = true
Consistent if x and y is not modified x.equals(y) alwaysreturns same result
X.equals(null) always returns false
8/13/2019 Programming Best Practices in Java
14/39
2010 IBM Corporation
common mistake #1
Class X {
public boolean equals(X other) {
//logic for equality
}
}
Merely another method in your class.
Follow the API specification for declaring the
equals() method
Class X {
public boolean equals(Object other) {
//logic for equality
}
}
8/13/2019 Programming Best Practices in Java
15/39
2010 IBM Corporation
common mistake #2
Class X {
int value;
public boolean equals(Object other) {
return this.value == ((X)other).value;
}
}
Blind casting
Code that will fail
X x = new X(10);
if(x.equals(10)) {
//other code
}
Correct way to do it
public boolean equals(Object other) {
if(other instanceof X) {
return this.value == ((X)other).value
}
return false;
}
8/13/2019 Programming Best Practices in Java
16/39
2010 IBM Corporation
common mistake #3
public boolean equals(Object other) {
if(other instanceof X) {
return this.value == ((X)other).value
} else if (other instanceof String) {
return this.value ==Integer.parseInt((String)other);
}
return false;
}
Contract breachif x.equals(y) = true then y.equals(x) = true
X x = new X(100);String s = 100;x.equals(s); //trues.equals(x); //false
8/13/2019 Programming Best Practices in Java
17/39
2010 IBM Corporation
#6 hashCode() contract
Always override this method if
equals() method is overriddenClass instances will be used as keys in hash basedcollections like HashSet, HashMap, Hashtable
Typical behaviorTwo objects which are not equal should generatedistinct integer values for hashCode(). Guarantees
good performance for hashtables.
Use well known hashing techniques for even
distribution.
The contract
Returns same integer value when invoked any numberof times during the application execution provided
no information used in equals comparison havechanged.
x.equals(y) = true then x.hasCode() == y.hashCode()
8/13/2019 Programming Best Practices in Java
18/39
2010 IBM Corporation
common mistake #1
Class X {
int value;
public boolean equals(Object other) {
return this.value == ((X)other).value;
}
}
HashMap map = new HashMap();
map.put(new X(100), century);
String term = (String)map.get(new X(100));System.out.println(term);
Output: null
Note 2 different instances of X are used for put and getGet method will end up looking into a different bucket for the value
as System.identityHashcode() will for hashing the keys
Reason: equals() overridden but hashCode() missed
Implement hashCode() method to fix the problem
8/13/2019 Programming Best Practices in Java
19/39
2010 IBM Corporation
common mistake #2
Return the same value as hashCodeClass X {
int value;
public boolean equals(Object other) {
return this.value == ((X)other).value;
}
public int hashCode() {
return 1;
}
}
HashMap map = new HashMap();
for(int i = 0; i < 1000; i++) {
map.put(new X(i));}
Code will work fine but!!
All the instances get hashed to the same bucket rendering HashMap useless
8/13/2019 Programming Best Practices in Java
20/39
2010 IBM Corporation
#7 toString ()
create a string representation for essential elements in yourclass
Make it easy to distinguish one object from other
Helps debugging, logging.
Document the string representation for others to understand whatis being returned
Default behaviorReturns a string which looks like YourClass@153fa5
8/13/2019 Programming Best Practices in Java
21/39
2010 IBM Corporation
#8 consider implementing Comparable
Tells others that the object of this class can have a natural order
Can use Arrays.sort().
Can be inserted into collections that retain objects by natural order e.g.
TreeMap, PriorityQueue
The contractsignum(x.compareTo(y)) == -signum(y.compareTo(x));x.compareTo(y)>0 && y.compareTo(z)>0 implies x.compareTo(z)>0x.compareTo(y) == 0 implies signum(x.compareTo(z)) ==signum(y.compareTo(z);
8/13/2019 Programming Best Practices in Java
22/39
2010 IBM Corporation
Classes and Interfaces
8/13/2019 Programming Best Practices in Java
23/39
2010 IBM Corporation
#9 Minimize the accessibility of classes and members
Well designed class hides all of its implementation
Make each class or member as inaccessible as possible.
Start with private.
Resort to package-private if other classes in same package need
access.
Protected members once exposed would need to be always retained
as protected.
8/13/2019 Programming Best Practices in Java
24/39
2010 IBM Corporation
#10 Never expose static final array objects
Security riskpublic static final Type[] VALUES = { ... };
Array itself cannot be replacedArray elements can be replaced
Use private array and immutable public listprivate static final Type[] PRIVATE_VALUES = { ... };
public static final List VALUES =
Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
Use a cloneprivate static final Type[] PRIVATE_VALUES = { ... };
public static final Types[] values() {return (Type[]) PRIVATE_VALUES.clone();
}
8/13/2019 Programming Best Practices in Java
25/39
2010 IBM Corporation
#11 Favor immutability
Immtuable ojectsNever change stateInherently thread safeShared and reused freely
Thumb rules
No mutators exposedMake class finalMake all fields private and finalExclusive access to mutable component
Never use externally provided references
directly in your class
Never give out references to members
8/13/2019 Programming Best Practices in Java
26/39
2010 IBM Corporation
#12 Composition over inheritance
InheritanceBreaks encapsulation (subclass depends on implementationdetails of superclass
Subclass breaks if super class changes
CompositionMake the class a member of your implementationUse call forwarding to explore the implementation
Document for inheritance else use finalEffects of overriding a method for each public and protected
members
Overridable methods being invokedOrder of invocation and how results affect subsequentinvocation
DontsConstructor should not invoke overridable methodsclone() OR readObject() method should not invoke overridable
methods
Make readResolve() or writeReplace methods protected
8/13/2019 Programming Best Practices in Java
27/39
2010 IBM Corporation
#13 Interface over abstract class
InterfacesNo method implementationsExisting classes can be modified to implement new interfacesIdeal for defining mixins
Does not impose hierarchiesEvolution is not very easy
Abstract classCan provide some base reusable functionalityExisting classes cannot be easily modified to extend
Easy evolutionSubclass breaks is super class changes
CombinationCombine interfaces with abstract class to create a skeletal
implementation class
Called AbstractInterface
8/13/2019 Programming Best Practices in Java
28/39
2010 IBM Corporation
Methods
8/13/2019 Programming Best Practices in Java
29/39
2010 IBM Corporation
#14 Method parameters and return values
Parameter ValidityDocument and enforce parameter restrictionsFail quick and clean. Especially for parameters stored forlater use.
Throw only documented exceptions.Validity check is practical if not costly
Not practical to check if array passed in binary search issorted.
Method Signatures
Avoid long parameter listFavor interface names for parameters over classes
Return valuesReturn zero length arrays instead of nulls
8/13/2019 Programming Best Practices in Java
30/39
2010 IBM Corporation
#15 Method overloading
public class CollectionClassifier {public static String classify(Set s) {
return "Set";
}
public static String classify(List l) {
return "List";
}
public static String classify(Collection c) {
return "Unknown";
}
public static void main(String[] args) {
Collection[] tests = new Collection[] { new HashSet(), new ArrayList(),
new HashMap().values()
};
for (int i = 0; i < tests.length; i++) {
System.out.println(classify(tests[i]));
}
}
}
Output is NOT Set, List, Unknown
Decision made at compile time
8/13/2019 Programming Best Practices in Java
31/39
2010 IBM Corporation
General programming
8/13/2019 Programming Best Practices in Java
32/39
2010 IBM Corporation
#16 General tips
Minimize scope of local variablesDeclare where used first
Initialize the local variables
String concatenationNew object created every timeUse StringBuffer.append instead
Native methodsCost involved in calling a native method from java and backPossibility of corrupting arguments passed due to additionalcontrol native code has.
Java now provides performance at par with native code
Refer objects by interface
List v/s Vector
Do not use float/double for monetory calculations. UseBigDecimal, int or long
System.out.println(1.03 0.42);Output: 0.6100000000000001
8/13/2019 Programming Best Practices in Java
33/39
2010 IBM Corporation
Exceptions
8/13/2019 Programming Best Practices in Java
34/39
2010 IBM Corporation
#17 Exceptions are for Exceptional conditions only
Expensive to create, throw and catch Exceptions
Do not force catching of exceptions on callers
What if InputStream.isAvailable() was not provided
Do a null check instead of catching a NullPointerException
CheckedExceptions are recoverable conditions
RuntimeExceptions suggest programming errors and are not always
recoverable.
Use existing standard Exceptions. E.g. IllegalArgumentException
Use Exception chaining HigherLevelException(LowerLevelException t)
Do not catch and ignore the exception. At least document why
you are ignoring
8/13/2019 Programming Best Practices in Java
35/39
2010 IBM Corporation
Threads
8/13/2019 Programming Best Practices in Java
36/39
2010 IBM Corporation
#18 Multithreading Dos and Donts
Synchronize access to shared mutable resources
Avoid excessive synchronization.
Maintain lock ordering to avoid deadlocks
Spend as little time as possible in a synchronized block Invoke wait() inside a loop on the satisfying condition.
Thread scheduler does not work as expected.
Do not use a sleep while holding a lock
Document thread safety aspects of your code
8/13/2019 Programming Best Practices in Java
37/39
2010 IBM Corporation
IBM Corporation 2012. All Rights Reserved.
IBM, the IBM logo, ibm.com are trademarks or registeredtrademarks of International Business Machines Corp.,
registered in many jurisdictions worldwide. Other product and
service names might be trademarks of IBM or other companies.A current list of IBM trademarks is available on the Web at
Copyright and trademark information atwww.ibm.com/legal/copytrade.shtml.
Copyright and Trademarks
8/13/2019 Programming Best Practices in Java
38/39
2010 IBM Corporation
Questions?
8/13/2019 Programming Best Practices in Java
39/39
2010 IBM Corporation39
References
Effective Java Programming Language Guide Joshua Bloch
Get Products and Technologies: IBM Java Runtimes and SDKs:
https://www.ibm.com/developerworks/java/jdk/
IBM Monitoring and Diagnostic Tools for Java: https://www.ibm.com/developerworks/java/jdk/tools/
Learn:
IBM Java InfoCenter: http://publib.boulder.ibm.com/infocenter/java7sdk/v7r0/index.jsp
Discuss: IBM Java Runtimes and SDKs Forum:
http://www.ibm.com/developerworks/forums/forum.jspa?forumID=367&start=0