Beruflich Dokumente
Kultur Dokumente
Until I find time to get more organized, here are a number of miscellaneous note
s assembled when I find answers to Java questions and don't want to have to go l
ooking for them again.
Links
Java: Four Security Vulnerabilities Related [to] Coding Practices to Avoid, (htt
p://java.dzone.com/articles/java-four-security)
Reduce Boilerplate Code in Java with Lombok (http://java.dzone.com/articles/redu
ce-boilerplate-code-your)
http://java.dzone.com/articles/top-10-easy-performance
http://eclipse.dzone.com/articles/10-most-important-security
Got Java?
Because I work on Linux, in the past years I've migrated to using OpenJDK. Howev
er, when I need Sun's Java (no, I don't mean Oracle's I'm still a little in denial
about that), I go to http://java.sun.com. There I can get it for any platform,
including Apple Macintosh OS X.
Because I write software in Java, I download a JDK "privately" which is to say t
hat I put it locally to my user, on a path like /home/russ/dev/jdk1.7.0_51. On M
acintosh OS X, which I think give one little-to-no say in the matter, this appar
ently ends up being more like /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/
Contents/Home. (I don't use Macintosh, but one day I might again so this isn't c
ompletely irrelevant.)
Use of static...
A static variable in a class becomes a single instance for all instantiations of
objects of that type. If changed by one, it's changed for all objects. static f
inal will ensure its inability to be modified.
Declare immutable constants as static final. This guards against inadvertant mod
ification and permits the compiler to perform optimizations in the use of those
values.
Identifier case...
Use camel-back, lower-case initial in the names of methods and non-constant vari
ables.
Width of characters...
A char cannot be safely converted to byte.
Flow-control...
Never use exceptions for flow-control.
Use of .class...
String className = ASConfig.class.getName();
Given <class-type> .class. <method>
.class gets the Class object for the class-type and calls the indicated method.
In the sample above, the class name is returned.
See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.8.
2
Accessors and mutators
..are formal names for getters and setters.
Conversions
int to String
int x = 99;
String X = Integer.toString( x );
// or
String X = "" + x;
JUnit testing
See junit.html.
Integers in Java
Type Size Range
name bytes bits minimum maximum
byte 1 8 -128 +127
short 2 16 -32,768 +32,767
int 4 32 -2,147,483,648 +2,147,483,647
long 8 64 -9,223,372,036,854,775,808 +9,223,372,036,854,775,8
07
Instance variable instantiation
Consider the following class and subclass which illustrate a bizarre point of in
stance variable initialization. It might be a long time if ever someone actually
suffers from this problem, but it makes a useful observation on initialization.
The explanation here is a bit awkward and over-stated, but clear, I think.
class Abc
{
public Abc( Object o )
{
assignValue( o );
}
public void assignValue( Object o )
{
// do nothing...
}
}
public class Test extends Abc
{
public Object x = null;
public Test( Object o )
{
super( o );
}
public void assignValue(Object o)
{
x = o;
System.out.println( "x in assignValue: " + x );
}
public static void main( String args[] ) throws CloneNotSupportedExcep
tion
{
Test t = new Test( "Test" );
System.out.println( "t: " + t.x );
}
}
Output:
x in assignValue: Test
t: null
The output happens because the initialization:
public Object x = null;
executes after the constructor. So...
x = 0;
gets overwritten by
public Object x = null;
The secret is that the compiler in fact arranges to call the explicitly invoked
superclass constructor before the (local) constructor will get executed.
The initializations done as part of the class instance variable declarations are
part of and occur before the (local) construction process. In our example, they
occur implicitly before the statements in the (subclass) constructor, with the
exception of the superclass constructor invocation as noted.
Therefore, execution order is not straightforward as it is in C. Hence, here the
null initialization runs after the local class' call of its superclass construc
tor. The compiler in essence absorbs the
super( o );
statement and runs it before any other constructor statements as well as even be
fore applying the initializations stated in the instance variable declarations.
See http://forums.sun.com/thread.jspa?forumID=31&threadID=5260093.
I/O
Here's a good site for sample code: http://www.exampledepot.com/egs/java.io/pkg.
html
See also sample code in com.etretatlogiciels.samples.fileio.
Synchronization in Java
This is not an exhaustive treatment of concurrency solutions in Java. It is a si
mple treatment, from a C programmer's mentality, of the Java keyword, synchroniz
ed. Java uses this keyword in two ways.
Synchronized blocks
The synchronized keyword is used to synchronize a block of executable statements
by referring to an object. This object becomes like a mutex in procedural progr
amming languages: executing all other blocks with reference to object is seriali
zed:
Object object = new Object();
synchronized( object )
{
do something with object;
}
How it works
On its face, object is not any kind of mutex, condition variable, reader-writer
lock, barrier or other synchronization primitive that you would expect to declar
e in a procedural language to manage your protected data in parallel. But in fac
t, every Java object contains a lock within itself. This lock is formally referr
ed to as a monitor. When the compiler sees synchronized in this situation, it ge
nerates code to use the object's monitor.
Synchronized methods
The synchronized keyword is also used to synchronize goings on in a method. This
is also like controlling execution of the method based on a mutex, but the obje
ct is implied this rather than explicit.
synchronized void makeSomeoneHappy()
{
do something to make someone happy with several objects;
}
All synchronized methods share the same mutex (this, as noted). The above is dir
ectly equivalent to:
void makeSomeoneHappy()
{
synchronized( this )
{
do something to make someone happy with several objects;
}
}
Watch out!
A private member variable in a class isn't safe unless all methods touching it a
re explicitly synchronized. A public member variable would practically never be
safe. In the following class, x is safe, but y is not even though their manipula
ting methods are synchronized.
public class TwoCounters
{
private int x = 0;
public int y = 0;
public synchronized getX() { return this.x; }
public synchronized incX() { this.x++; }
public synchronized zeroX(){ this.x = 0; }
public synchronized getY() { return this.y; }
public synchronized incY() { this.y++; }
public synchronized zeroY(){ this.y = 0; }
}
This is because code outside this class can freely access y whereas an attempt t
o access x would be rebuffed by the compiler:
TwoCounters counter = new TwoCounters();
counter.y = 99; PASSES COMPILER, BUT A BAD IDEA!
counter.x = 99; COMPILATION ERROR!
The distinction between the two methods of synchronization just contrasted is th
at in the second case, no actual, explicit object is needed in writing the code
to perform serialization. There is no need to create object. Instead, the implie
d object, this, is used.
(Yup, this is absolutely the first time in over a decade of writing HTML that I
have used the <blink> tag: very annoying, isn't it?)
Deadlocking
Between correctly synchronized methods in diverse classes deadlocks can easily o
ccur, in particular, the ABBA. The following is the scenario.
Thread A enters a synchronized method for class Foo. It holds the monitor for Fo
o's this. Let's say that thread A blocks momentarily on some I/O operation.
Thread B enters a synchronized method for class Bar. It holds the monitor for Ba
r's this. Thread B also knows about the same instance of Foo as thread A and att
empts to enter one of Foo's synchronized methods. Foo's monitor is contested bec
ause thread A already has it.
Thread A wakes up from its I/O operation and, having a reference to the instance
of Bar that thread B already has locked, decides to attempt to enter one of Bar
's synchronized methods.
Thread A is blocked on a monitor held by thread B and thread B is blocked on a m
onitor held by thread A.
This sort of nightmare is best prevented by careful design. The temptation by ba
d engineers in a procedural language might be to test whether a lock is going to
be contested before attempting to use it and, indeed, it is sometimes impossibl
e to do otherwise. However, all efforts to design logic to avoid doing this shou
ld be made. Moreover, as noted next, it was not possible prior to Java 1.5 to pe
rform a try-lock.
System properties
Much is configurable in Java and:
String property = System.getProperty( property-name);
...is how a property is got. There are three ways they are set.
First, Sun sets them, like java.io.tmpdir, predefined, in its JRE. Other JREs do
too and, from platform to platform, there is sometimes the tiniest bit of non-c
onformance.
Second, you can set them yourself using the command line:
# java -Dhow.i.feel=blue MyClass
Last, you can set them programmatically:
String libraries = System.getProperty( "java.library.path" );
if( libraries != null && libraries.length() != 0 )
libraries += ":" + "/home/russ/dev/libs";
else
libraries = "/home/russ/dev/libs";
System.setProperty( "java.library.path", libraries );
File.createTempFile()
A temporary file is created in java.io.tmpdir:
File f = File.createTempFile( "fun", ".poo" );
System.out.println( "Just created file "
+ f.getName()
+ " in directory "
+ System.getProperty( "java.io.tmpdir" )
);
Encapsulation is...
...these three things, most importantly:
Separation of concerns, a phrase borrowed from Edsger Djikstra, 1975.
"Let me try to explain to you, what to my taste is characteristic for all intell
igent thinking. It is, that one is willing to study in depth an aspect of one's
subject matter in isolation for the sake of its own consistency, all the time kn
owing that one is occupying oneself only with one of the aspects. We know that a
program must be correct and we can study it from that viewpoint only; we also k
now that it should be efficient and we can study its efficiency on another day,
so to speak. In another mood we may ask ourselves whether, and if so: why, the p
rogram is desirable. But nothing is gained on the contrary! by tackling these vari
ous aspects simultaneously. It is what I sometimes have called "the separation o
f concerns", which, even if not perfectly possible, is yet the only available te
chnique for effective ordering of one's thoughts, that I know of."
An object's information (data) is separate from its interfaces.
Information-hiding, a term borrowed from David Parnas, 1972.
"We have tried to demonstrate by these examples that it is almost always incorre
ct to begin the decomposition of a system into modules on the basis of a flowcha
rt. We propose instead that one begins with a list of difficult design decisions
or design decisions which are likely to change. Each module is then designed to
hide such a decision from the others."
C.f. Java's private and, to a lesser extent, protected modifiers.
Ripple effects, a term borrow from Wayne Stevens, 1974.
"The fewer and simpler the connections between modules, the easier it is to unde
rstand each module without reference to other modules. Minimizing connections be
tween modules also minimises the paths along which changes and errors can propag
ate into other parts of the system, thus eliminating disastrous, 'Ripple effects
,' where changes in one part causes errors in another, necessitating additional
changes elsewhere, giving rise to new errors, etc."
I.e.: coupling and cohesion.
Problems with supposed encapsulation
Encapsulation is popularly implemented through usage of private attributes with
accessors. Using this method to achieve encapsulation when the attribute is a ja
va.util.Collection, java.util.Map, etc. is just plain wrong.
public class MyBean
{
private Collection collection;
public Collection getCollection() { return collection; }
public void setCollection( Collection collection ) { this.collection = colle
ction; }
}
...or even eschewing the setter by using a constructor:
public class MyBean
{
private Collection collection;
public MyBean( Collection collection ) { this.collection = collection; }
public Collection getCollection() { return collection; }
}
...will not make the interior collection immutable since a handle to it on the o
utside will make it modifiable. The following could be tried:
public class MyBean
{
private List collection = new ArrayList();
public MyBean( Collection collection ) { this.collection.addAll( collection
); }
public Collection getCollection() { return Collections.unmodifiableList( col
lection ); }
}
Tracking down memory leaks in Java
Here is an article: Monitoring and Detecting Memory Leaks in Your Java Applicati
on.
Note that thread-local store use and web applications running in a container lik
e Tomcat can easily sport memory leaks that must be cogitated and analyzed.
UnsupportedClassVersionError in Java
When you see a stack trace with...
java.lang.UnsupportedClassVersionError: SomeClass : Unsupported major.minor
version 51.0 (unable to load class SomeClass)
.
.
.
...it probably means that you compiled your application with a Java compiler of
a more recent version than the JVM you're trying to run it on.
Java collections
The Java collection consists of Sets, Lists and Queues:
Lists
Lists can contain duplicates, even LinkedList. If you want to eliminate duplicat
es (automatically), use a Set-type. What's different between types of lists is t
he speed of certain operations and this is how to pick which one to use in a giv
en situation.
ArrayList - dynamically sizing array. Fast random-read access, get() takes const
ant time. Adding and removing require shifting of the array elements in memory,
however. When the size of the array must be increased due to addition, a new arr
ay of size 150% is allocated and the old array must be copied. The default, unsp
ecified size (Java 4 through 7) is 10. Constructing it with more saves time if y
ou know there will be more.
ArrayList is hugely expensive for remove operations and for add operations when
the size allocated is used up.
Vector works like ArrayList, but is synchronized and therefore thread-safe and sli
ghtly slower. Most programmers eschew this in favor of ArrayList since they want
to synchronize explicitly anyway.
LinkedList - doubly linked list. Best for constant-time insertions and sequentia
l access of elements. Finding a position in the array takes time proportional to
the length of the list. The size penalty for the overhead grows considerably ov
er that for ArrayList at, on a graph, almost a 45 angle. (Note: since late Java 6
, no distinction between 32-bit and 64-bit is distinguishable 64-bit used to have
even more overhead.)
better for add and remove than ArrayList, worse for get and set operations. Use L
inkedList if there are going to be few random accesses (get(), contains()) or ma
ny add or remove operations. See http://www.programcreek.com/2013/03/arraylist-v
s-linkedlist-vs-vector/.
HashMap is like an ArrayList of key-value pairs, but it is not implemented withi
n the framework of Java collections (it's not a set, list or queue). It is a Map
. Keys in a map cannot occur in duplicates.
Sets
In a set, no duplicates are allowed. When adding, duplicates are removed automat
ically. The three most commonly used sets implementations are HashSet (fast), Li
nkedHashSet (order-preserving) and TreeSet (maintained sorted).
HashSet - elements are unordered, held in a hash table. Add, remove and contain
operations have constant-time complexity.
LinkedHashSet - is a sort of hash table with a linked list running through it, m
aintaining the order of insertion.
See http://www.programcreek.com/2013/03/hashset-vs-treeset-vs-linkedhashset/.
Queues
(Not today.)
Java maps
The Java map consists of HashMap, LinkedHashMap, TreeMap and Hashtable.
HashMap - makes no guarantee as to order, allows one null key and null values. T
raversed using iteratory, entry set. (Inherits AbstractMap.)
LinkedHashMap - preserves the original insertion order, but is otherwise identic
al to HashMap.
TreeMap - uses natural or comparator-based ordering to maintain contents in-orde
r. Null keys only allowed if comparator used and doesn't thrown an exception.
Hashtable - makes no guarantee as to order, disallows null keys and values, is s
ynchronized and therefore expensive if you don't need that. Traversed using enum
erator and iterator. (Inherits Dictionary.)
Java filepaths
You try to create a file. Where is it? Original, Windows code:
File child = new File(".././Java.txt");
getPath() likely relative to current working subdirectory.
..\.\Java.txt
getAbsolutePath() fully qualified path, but in relationship to the current workin
g subdirectory.
C:\Users\WINDOWS 8\workspace\Demo\..\.\Java.txt
getCanonicalPath() full path from the filesystem's point of view.
C:\Users\WINDOWS 8\workspace\Java.txt
byte[] to String
byte[] aByte = new String( ".976" ).getBytes();
String propertyValue = new String( aByte );
...otherwise, aByte.toString() yields gobble-dee-gook.
Exceptions
... exist in checked and unchecked varieties. The original idea:
Unchecked exceptions represent defects in the application code, perhaps a null p
ointer, an invalid argument passed to a non-private method. These represent cond
itions that, generally speaking, reflect errors in logic and cannot be reasonabl
y recovered from at runtime.
At least that was the theory in the 1990s.
Checked exceptions are invalid conditions in area outside immediate control of a
pplication code including invalid user input, database problems, network outages
, absent files, etc.
They are subclasses of Exception.
Methods are oblged to establish a policy for all checked exceptions thrown by it
s implementation (either by passing the problem further up the stack or throwing
again to be handled elsewhere).
If a client can reasonably be expected to recover from an exception, make it a c
hecked one. If unreasonable, make it unchecked.
Checked/unchecked exceptions
1. Throwable and Error classes should not be caught
Throwable is the superclass of all errors and exceptions in Java. Error is the s
uperclass of all errors which are not meant to be caught by applications. Thus,
catching Throwable would essentially mean that Errors such as system exceptions
(e.g., OutOfMemoryError, StackOverFlowError or InternalError) would also get cau
ght. The recommended approach is that an application should not try to recover f
rom errors such as these. Therefore, Throwable and Error classes should not be c
aught. Only Exception and its subclasses should be caught.
Data errors such as encoding issues etc which are not known at programming time
should be caught using this technique. However, catching Throwable such as Inter
nalError or OutofMemoryError would not be of any help and should never be thrown
.
Avoid writing code consisting of catching Throwable as general practice.
2. Throwable.printStackTrace( ) should never be called
One should avoid invoking printStackTrace() method on Throwable/Exception classe
s and instead use a logging framework.
3. Generic exceptions Error, RuntimeException, Throwable and Exception should ne
ver be thrown
The primary reason to avoid throwing generic Exceptions, Throwable and Error is
that doing so prevents classes from catching the intended exceptions. A caller c
annot examine the exception to determine why it was thrown and consequently cann
ot attempt recovery.
Catching RuntimeException is considered a bad practice. Throwing generic Excepti
ons/Throwable leads the developer to catch the exception at a later stage which
usually leads to worse practices.
Do not throw a generic exception like RuntimeException. Do, however, throw a cus
tom-rolled exception that inherits from RuntimeException.
4. Exception handlers should preserve the original exception
5. System.out or System.err should not be used to log exceptions
The primary reason one should avoid using System.out or System.err to log except
ions is that one might simply loose the important error message.
Checked exceptions!
One man's opinion...
It is an utterly failed experiment because it is designed around the totally fla
wed assumption that the service/library throwing the exception should decide whi
ch ones should be checked and which ones should not. In reality, only the caller
knows which ones should be caught (usually none), and which ones should not.
6. Generally, whenever a library-method is called that throws a checked exceptio
n, just do:
try
{
libraryObject.method();
}
catch( Exception e )
{
throw new MyAppRuntimeException( e );
}
...to prevent this checked-exception idiocy from propagating like a virus and in
fecting the whole application.
Random in Java
Check out these claims when you get a chance.
view sourceprint?
import java.lang.reflect.Field;
import java.util.Random;
public class Entropy {
public static void main(String[] args)
throws Exception {
// Extract the IntegerCache through reflection
Class<?> clazz = Class.forName(
"java.lang.Integer$IntegerCache");
Field field = clazz.getDeclaredField("cache");
field.setAccessible(true);
Integer[] cache = (Integer[]) field.get(clazz);
// Rewrite the Integer cache
for (int i = 0; i < cache.length; i++) {
cache[i] = new Integer( new Random().nextInt(cache.length));
}
// Prove randomness
for (int i = 0; i < 10; i++) {
System.out.println((Integer) i);
}
}
}
Reverse string
view sourceprint?
public class StringReverse
{
private static final String[] FODDER =
{ // palindromes except the first...
"Off to the races...",
"Madam I'm Adam",
"A dog, a plan, a canal: pagoda",
"A nut for a jar of tuna",
"A Santa at NASA",
"A slut nixes sex in Tulsa",
"A car, a man, a maraca"
};
private static String reverse( String string )
{
if( string.length() < 2 )
return string;
/* Algorithm: Grab everything after the first character and return
* it followed by the (soon to be former) first character itself.
*/
return reverse( string.substring( 1 ) ) + string.charAt( 0 );
}
public static void main( String[] args )
{
for( String string : FODDER )
{
String message = "String " + string + " ";
int TAB = 40, length = message.length();
System.out.print( message );
while( length++ < TAB )
System.out.print( " " );
System.out.println( " reversed is: " + reverse( string ) );
}
}
}
Output:
String Madam I'm Adam reversed is: madA m'I madaM
String Off to the races... reversed is: ...secar eht ot ffO
String A dog, a plan, a canal: pagoda reversed is: adogap :lanac a ,nalp a ,
god A
String A nut for a jar of tuna reversed is: anut fo raj a rof tun A
String A Santa at NASA reversed is: ASAN ta atnaS A
String A slut nixes sex in Tulsa reversed is: asluT ni xes sexin tuls A
String A car, a man, a maraca reversed is: acaram a ,nam a ,rac A
Arrays.toString() minus the brackets
Arrays.toString( array ) surrounds the whole with "[ ... ]" not what we want.
view sourceprint?
private String arrayToString( String[] array )
{
StringBuilder sb = new StringBuilder();
boolean first = true;
for( String particle : array )
{
if( !first )
sb.append( ' ' );
sb.append( particle );
first = false;
}
return sb.toString();
}
EarlyExitException is not EarlyExitException (symbol is not symbol)
Beware (duh!) that if you have a duplicate class, EarlyExitException, in your co
de and are building using a JAR that also has that symbol, uses and throws it, y
our code will not be catching it just because you happen also to have EarlyExitE
xception. They are different and you get errors like
unreported exception EarlyExitException; must be caught or declared to be thrown
because EarlyExitException is not EarlyExitException.