Java
This page will be a collection of resources on Java programming.
Documentation
- Thinking in Java. This links to a mirror for the third edition.
- Official Sun documentation.
- Almost everything can be found in the API Javadocs. Java libraries are very well designed, and very well documented (Javadocs rule!).
Differences from C++
- Inner classes: Although nested classes exist in C++, they are rarely used, and anyway it seems that the only effect of nested classes is on namespaces. Inner classes in Java have the interesting features that they can access their enclosing class object, and all of its members, directly.
- Inner local classes: Local classes defined inside a statement block (a function block for example) can even access the final local variables of the function. Nice!
- Anonymous inner classes: When you define the body of a class directly after a new keyword, you are defining an anonymous class. This class can derive from an existing class or implement an interface. The syntax is:
MyInterface my_instance = new MyInterface() { // Here you write the body of the class { // Here we could perform instance initialization } };
You cannot have a constructor in an anonymous class since the class does not have a name. You can, however, pass arguments to the base constructor, and you can also perform instance initialization (see the previous code).
Note that with anonymous classes, you cannot have more than one object of the class. This limitation is not present with inner local classes, so the only point of an inner local class (vs. an anonymous class) is to create more than one instance of the class.
- Note that there is no such thing as anonymous or inner interfaces. What you do generally, however, is create a class that will implement an interface.
Various notes
- Strings are encoded in memory using UTF-16 encoding, but this is generally transparent: when you output to a stream (file, console, etc), it will be converted to another encoding that's dependent on your system locale.
Standard Library from the JDK
- There is no first() nor last() methods on ordered collections! This is surprising. Note Groovy has the pop() method for removing the last element of a list.
- The clone() method performs a shallow copy of an object instanced. Sometimes it is best to hand write a copy constructor yourself, as when using clone() you don't have much control over what gets copied.
Collections
- Be careful that a Map, for example, does not implement the Collection interface, even if it is part of the collection framework.
Libraries
Log4J
- Log4J is an excellent high performance logging library. Log4J has 3 core concepts: loggers (objects that you obtain for logging), appenders (loggers use different appenders to direct the log output to various places) and layouts (how the log will be formatted).
- One thing that's worth noting is that the logging level is defined on the loggers, not on the appenders. Thus it is not possible to tell a logger to use different logging levels depending on the appender. In that case, a workaround is to define a threshold on the appender. In practice, this works fine.
- You can provide the path to the Log4J configuration file by providing a Java property setting on the command line:
java -jar msample.jar -Dlog4j.configuration=/path/lib/log4j.properties
- In the Log4J configuration file, you set up the properties of the beans via the standard Java beans ways, by using the setters convention (thus lookup the Javadoc to know which configuration options are available).
- Formatting is controlled by the layout objects. Good link to the Javadoc.
Commons I/O
- Excellent library if you need to perform simple file system tasks such as recursively copy directories, move files, etc. The standard Java library only provides low level means of dealing with files, which makes this library very useful.
Dozer
- Don't forget than you need to have a default constructor in order for Dozer to correctly instantiate the destination objects.
- If you are not using Java 1.5, and you are dealing with a collection mapping, you must provide hints regarding the collection contents. Else it will assume the target collection contains the same objects than the source collection (which often is not the case).
FileUpload
- If you use a HTTP POST request with the multipart/formdata encoding, probably the HTTP headers won't include the encoding. At least that happens when using Firefox and GWT. So on the server side, Java won't know which encoding to use for this ServletRequest. Directly setting the correct encoding on the request object does not work later with fields retrieved via the FileUpload API. You have to explicitly provide the encoding when retrieving those fields:
file_item.getString(request.getCharacterEncoding());
This would work if you previously set the request encoding (else you can just provide "UTF-8" directly).
JEE
- The servlet API included in the early versions a method to parse a query string into a map of parameters. This method is now deprecated, probably because newer versions of the API include much better techniques (request.getParameterMap for example). However, it can still be useful to parse such a query string outside of a servelt request. You have to write the method yourself, the best is to use Matcher and Pattern classes of regular expressions.
Java Beans
- In a Java properties file, you can set the properties of Java beans by using the setter convention. For example if a bean has a setLogging() method, you could activate logging by writing in your .properties file:
myBean.logging=true
Java Servlets
- Java servlets can easily access information from GET or POST HTTP requests via the function getParameter("key");. However if you are using a FileUpload servlet, in the POST request the information has to be encoded in a way that makes the standard official Java Servlet API fail. You *must* use the FileUpload API.
- To obtain the current working dir of a servlet, use
getServletContext().getRealPath("/");
Don't use System.getProperty("user.dir") as user.dir is a Java property that has nothing to do with the servlet context.
Hints & Techniques
- To round a float to the upper integer, use Math.ceil().