Java
Links und Literatur
- Java ist auch eine Insel
- Java in 21 Tagen
- Handbuch der Java-Programmierung
- Angelika Langer: JAVA
- Java Classpath
- Effective Java - Joshua Bloch
Start Java
Start Java with more memory
Enforce a certain Java Version
Compile and run Java Programs
The separator in Windows is not ":" but ";".
This is how you use a .java file to create a .class file
You need to list all jar files that you need to compile your code, but not the ones that you use indirectly during runtime
This is how you create jar files
See also how to create JAR files.
How to run you Java program (now you need all the jar files, also the ones that are indirectly called during runtime)
Java debug
When you start your Java program like this on an remote host you can connect to it with your IDE and debug the running program
This here ensures that the program waits for your debugger to connect before it starts, so you do not miss the start
In Eclipse you can configure the debugger like this
remote java application
new
hostname + port where your program runs
Data Containers
Java Classes
Autoboxing
Integer j = i; // j = Integer.valueOf(i)
int k = j; // k = j.intValue()
Equality
Foo a, b;
x==y // (1)
a==b // (2)
a.equals(b); (3)
- For primitive types just compares if they have the same value
- For non primitive types checks if both names point to the same object in memory
- This is the way to check if they have the same value, but you need to implement equals correctly for your classes for this to work
If you do not implement equals for your classes, this is the default (only true if both names point to the same object in memory)
{
return ( this == obj );
}
Lets say you have a class that has an primitive attribute called bar and only if that is the same for two objects. Then a possible implementation for equals would be this
{
if ( obj instanceof Foo ) {
Foo tmp = (Foo) obj;
return (bar == tmp.bar)
}
return super.equals( obj );
}
Check that you really expect as parameter an Object and not the class that you write the equals method for. So NOT like this
When you implement equals be share that if a.equals(b) then also a.hashcode()==b.hashcode() (if the hash codes are equals objects can be not equal). Eclipse can implement reasonable defaults for equals() and hashcode().
When you compare objects watch out if one or both of them can be null. Always call equals on the one that can not be null, if both can be null check for null before you call equals Ist z.B. a potentiell null, b hingegen nicht, kann man das equals von a natürlich nicht aufrufen
b.equals(a); // needs at least b!=null
Objects.equals(a, b); // null safe
Conditional Expressions
You assign a value, which value depends on a condition
int max=(foo) ? 5 : 6;
Be carefule when the values you assign have different types.
Short-circuit evaluation
(German Kurzschlußoperatoren) When you have a OR b and a is already true you do not really need to check b (because no matter what b is, the result will be true anyhow). Similar with a AND b when a is false, result can not be true anymore. But maybe you want to evaluate b anyhow because it has some side effects (I would not recommend that). This is how you can control this
boolean b2 = true | foo(); // (2)
boolean b3 = false && foo(); // (3)
boolean b3 = false & foo(); // (4)
- foo() is not called
- foo() is called
- foo() is not called
- foo() is called
Compound Assignment Operator
x+=y; // (2)
x=+y; // (3)
- Normal assignment
- Short version of (1) but tries to cast y to the type of x
- Looks like (2) but just assigns x the value of y without any calculation
This is valid Java code (but unexpected result as 128 does not fit into a byte)
int y=128;
x+=y;
This is not valid Java code
int y=128;
x=x+y;
Also in (2) x has to be a primitive type (or boxed) or String
String y = "World";
x = x + y; // OK
x += y; // Error
Methods with flexible amount of parameters
The last parameter is then an array with all the values you provided
{
System.out.println(x.lenght);
}
foo("Hello", 1, 42, 8);
Hiding class attributes
private int x;
void foo(int x) {
this.x=x; // (1)
this.x = 12; // (2)
x = 12; // (3)
}
}
- assign the parameter to the attribute
- assign to the attribute
- assign to the parameter (bad style, make all parameters final
Override
Mark methods that override a method in a father class with this annotation
public void foo( int alter )
Lazy Initialization
Delay the (maybe expensive) initialization of classes until you really need them (maybe you will never need them after all)
Usually you may calculate values during object construction
private final Integer foo;
public Bar() {
foo=initFoo();
}
public Integer getFoo() {
return foo;
}
}
But you can delay that until it is read for the first time
private Integer foo;
public Bar() {
foo=null;
}
public synchronized Integer getFoo() {
if(foo==null)
foo=initFoo();
return foo;
}
}
For static attributes you can add a small static class that contains only that attribute and the calculation. Only when you use it for the first time in your main class the helper's class initalization will start. You don't need to add a synchronized.
private static class FooHolder {
static final Integer foo = initFoo();
}
static Integer getFoo() {
return FooHolder.foo;
}
But even when you have a non static attribute you can avoid the synchronized on the get method (which is expensive) by using the double-check idiom
private volatile Integer foo;
public Integer getFoo() {
// cheap check
Integer tmp=foo;
// only if still null check again with synchronized
if(tmp==null) {
synchronized(this) {
tmp=foo;
if(tmp==null)
foo=tmp=initFoo();
}
}
return tmp;
}
It is important that the attribute is volatile so changes to it will reach all threads. If a thread finds it to be still null the initialization will be done synchronized to avoid multiple initializations. If you don't mind multiple initializations you can skip this, that is called single-check idiom.
The local variable tmp is not required but is supposed to speed up the method.
final
Use final to prevent that values can be changed again
x=4; // (1)
final Foo y=new Foo();
y=new Foo(); // (2)
y.changeSomethingInside(); // (3)
- Not possible
- Not possible
- Still possible to call methods on y that change something internally (unless all attributes of Foo are also final)
Use final to prevent other classes to inherit from your class
{
// ...
}
Use final to prevent other classes to override your method
{
final void bar();
}
Exceptions
{
// ...
return 5;
}
catch ( Exception e )
{
System.err.println("Error");
}
finally
{
System.err.println("finally"); // (1)
return 7; // (2)
}
- finally block are exectued after the return or after an Exceptions have been caught
- returns in finally blocks are possible but not recommended. They overwrite the value of the actual return in the try block and if there was an exception it is lost
Finally
This is a small example to show the order in which your code is executed by having all return statements using a small helper method the "calculate" the return value. This method will print the result so you see the order
{
System.out.println("Here is your String value: "+pValue);
return pValue;
}
@SuppressWarnings("finally")
public static String doSomething(boolean pDoException)
{
System.out.println("Method entered");
try
{
System.out.println("Try block entered");
if(pDoException) throw new Exception("Bang!");
return getStringValueAndLogIt("NormalReturn");
}
catch(Exception e)
{
System.out.println("Exception occured");
return getStringValueAndLogIt("ExceptionReturn");
}
finally
{
System.out.println("Finally block entered");
// not recommended to have return in the finally block
return getStringValueAndLogIt("FinallyReturn");
}
}
Without Exception | With Exception |
---|---|
Method entered | |
Try block entered | |
Exception occured | |
Here is your String value: NormalReturn | Here is your String value: ExceptionReturn |
Finally block entered | |
Here is your String value: FinallyReturn | |
Return is "FinallyReturn" |
In both cases first the normal return is called and then then finally block. This makes sense, as the return itself may also cause an exception when calculation the return statement. The return in the finally block eventually overwrites the first return. This may be surprising.
Custom Exceptions
{
public MyException () {
}
public MyException ( String s ) {
super( s );
}
}
Java Generics
When you would have multiple almost identical classes that only differ by an inner type then maybe Generics in Java are a way for you to avoid code duplication
Javadoc
* @see Bar
* @link Bar
* @version 1.01
* @author John Doe
* @param x A number
* @param y Another number
* @return This method always returns 5
* @exception NumberFormatException
* @throws NumberFormatException
* @category Setter
* @deprecated Since yesterday
*/
public int foo(int x, float y)
{
return 5;
}
Stacktrace
jstack PID;
Assert
Conditions that if ever not true will throw an AssertionError exception
Sicherstellen dass die gegebene Bedingung erfüllt ist
assert i > 0 : "i must be greater than 0";
But it needs to be enabled when starting the program
java -enableassertions:bar foo
Multithreading
Files ander directories
Regular Expressions
https://www.baeldung.com/regular-expressions-java
With Backreference you can could parts out of a String a put them back together in a different way. Easy example you hava data in this format
and want to have it in this form
Then you could match day, month and year with a regular expression and access them afterwards with $1, $2, $3
- Regular expressions are slow and other String operations might be much better
- Especially for data formats there are other solutions, check for SimpleDateFormat or DateTimeFormatter in Java Data Time.
Create from a normal String a Regexp that matches the String (useful for creating escape characters) String s=java.util.regex.Pattern.quote("Hallo Welt");
This escapes the whole area
Reflection
try
{
c = Class.forName("foo");
} catch (ClassNotFoundException ex)
{
// ...
}
Annotations
Create your own Annotation
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface XMLGeneratorAnnotation
{
String elementName() default "";
int elemntOrder() default 0;
}
Check if a random object has your annotation on any attribute in it
{
f.setAccessible(true);
MyAnnotation a=f.getAnnotation(MyAnnotation.class);
try
{
f.getName();
f.get(myObject);
}
catch (IllegalArgumentException | IllegalAccessException e)
{
}
finally
{
}
}
Check all methods of a random object
{
m.setAccessible(true);
ElementContainer container=new ElementContainer();
MyAnnotation a=m.getAnnotation(MyAnnotation.class);
try
{
m.getName();
m.invoke(myObject);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
}
finally
{
}
}
Apache Commons
Very useful extra Java code for you Apache Commons.
Convert objects to Strings
String to Number
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Integer.html#parseInt
Integer.parseInt("042", 10);
0 Padding
Ensure String has 4 characters, if less add 0 at the beginning
Syntax:
Flags '0' (0 Padding) Conversion 'd' Integer, 'f' Float, 't' date, 'T' Time
Binary Code
See also BinaryCode
Long.toBinaryString(number);
Long.toBinaryString(Double.doubleToRawLongBits(number));
Java Properties
Useful to configure your program so you don't need code changes for that
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
...
// System properties (java -Dvariable=value)
Properties systemProperties=System.getProperties();
// Properties found in a file in the classpath, will also
// contain the values from the system properties
Properties fileProperties =new Properties(systemProperties);
URL url = ClassLoader.getSystemResource("MyProperties.properties");
fileProperties.load(new FileInputStream(new File(url.getFile())));
// Properties we will fill with the code during runtime
// will also contain the file properties (and with them also
// the system properties)
Properties extraProperties =new Properties(fileProperties);
// changes to the top level properties objects ...
systemProperties.setProperty("test.helloworld", "Hello world");
// ... are also reflected in their children
String message=extraProperties.getProperty("test.helloworld");
// debug output
extraProperties.list(System.out);
Java Preferences
Set preferences for the user that runs our program. Will be stored automatically in a per user configuration file. For Windows operating system in the registry
// read the already stored values
String name =prefsRoot.get( "name", "unknown");
Double weight =prefsRoot.getDouble( "weight", 0.0);
Boolean selected=prefsRoot.getBoolean("selected", false);
Long id= prefsRoot.getLong( "id", 0L);
// store new values
prefsRoot.put ("name", "John Doe");
prefsRoot.putDouble ("weight", 90.01);
prefsRoot.putBoolean("selected", true);
prefsRoot.putLong ("id", 1234567L);
JMX
Java Memory
- Stack: A method's local and primitive variables are stored on the stack.
- Heap: Newly created objects end up in Eden Space / "young generation". Objects there are statistically often created and quickly abandoned. After a Garbage Collector run, all objects that covered it go to Survivor Space. After a few runs, the surviving objects end up in the tenured generation / old generation. Moving the objects has costs, but this can result in contiguous memory areas.
- Non-heap memory: Cross-thread memory that the Java VM needs for internal purposes. E.g. information per class, method, constructors, but also constants. Called permanent generation, although memory need not be permanent. In addition, there is the code cache.
Links
- Java Heap Terminology
- Java storage management
- Java memory pool
- Permsize
- Permgen
- No Permgen
- Garbage Collector Paper
GUI with Java
Swing
Java in Websites
Java Applet
Java is run on the client computer Sun Java Applet Tutorial
import java.awt.Graphics;
public class HelloWorld extends JApplet
{
private static final long serialVersionUID = 1L;
public void init() {};
public void start() {};
public void stop() {};
public void paint(Graphics g)
{
g.drawRect(20, 20, getSize().width - 40, getSize().height - 40);
g.drawString("Hello world!", 40, 40);
}
public void destroy() {};
}
This is embedded in a website like this
JavaServer Pages and Servlets
Java is run on the server JavaServer Pages und Servlets
RMI and WebServices
Verteilte Programmierung mit RMI und WebServices
Java SSL
See content of the keystore
Enter keystore password: ********
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 1 entry
XXXX, 18.03.2014, PrivateKeyEntry,
Certificate fingerprint (SHA1): XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Check a jar with jarsigner for valid signatures
- Understanding Signing and Verification
- Signing JAR Files
- Verifying Signed JAR Files
- JUnit
- JUnit test case generation
- JUnit test editor
- Dependency Analysis
- Code Audit