Converting an integer to a hexadecimal (hex), octal or binary representation

Three useful functions in the Integer class do exactly this. Following program
demonstrates the use. Notice that the method toHexString returns the hexadecimal
representation in lowercase!

public class Main
{
   public static void main(String args[]) {
      int intValue = 65443;
 
      String hexValue = Integer.toHexString(intValue);
      String octValue = Integer.toOctalString(intValue);
      String binValue = Integer.toBinaryString(intValue);
 
      System.out.println(hexValue.toUpperCase());
      System.out.println(octValue);
      System.out.println(binValue);
   }
}

outputs:

FFA3
177643
1111111110100011

Convert a char to an int

eg.

char c = ‘A’;
int value = (char) c;

Following code demonstrates this. It prints out the ascii values of each letter
in a sentence:

public class Main
{
   public static void main(String args[]) {
      String s = "A woman doesn't have a banana";
 
      for (int i=0; i<s.length(); i++) {
         char c    = s.charAt(i);
         int value = (int) c;
 
         System.out.println(c + ": " + value);
      }
   }
}

prints out:

W: 87
o: 111
m: 109
e: 101
n: 110
 : 32
d: 100
o: 111
n: 110
': 39
t: 116
 : 32
h: 104
a: 97
v: 118
e: 101
 : 32
a: 97
 : 32
b: 98
a: 97
n: 110
a: 97
n: 110
a: 97

Converting an int to a char

eg.

int value = 65; // ascii for ‘A’
char c = (char) value;

Following code demonstrates this. It prints out an ascii table of printable characters.

public class Main
{
   public static void main(String args[]) {
      for (int i=33; i<255; i++) {
         System.out.print(i + ":");
         char c = (char) i;
         System.out.print(c + "tt");
         if ((i % 4) == 0) System.out.println();
      }
   }
}

Note that you may lose information converting a integer (four bytes) to
a character (two bytes):

int value = 65535;
char c = (char) value;		// convert to char
System.out.println((int) c);    // back to int, prints out 65536 (limit for char)

int value = 65536;
char c = (char) value;          
System.out.println((int) c);    // prints out 0

Dynamically loading and creating a class from a JAR

For this example, let’s create a JAR file called testjar.jar containing only one class in a package esus.testpackage. Create a directory structure:

   esus
     |
     +--- testpackage
               |
               +-------- TestClass.java

TestClass.java:

package esus.testpackage;
 
public class TestClass
{
   public void testMethod() {
      System.out.println("testMethod() called!");
   }
}

Compile and create a JAR file:

   javac esustestpackageTestClass.java
   jar cvf testjar.jar esus

Let’s not add this JAR file to the classpath, but dynamically use it to load a class and execute a method on it. For this purpose, use the URLClassLoader which takes a set of URLs pointing to JARs or directories.

Main.java:

import java.lang.reflect.*;
import java.net.*;
  
public class Main {
   public static void main(String[] args) {
      try {
         URL []urls = new URL[] { new URL("file:testjar.jar") };
 
         ClassLoader cl = URLClassLoader.newInstance(urls);
 
         // load class 
         Class c = cl.loadClass("esus.testpackage.TestClass");
 
         // create instance of class esus.testpackage.TestClass
         Object o = c.newInstance();
 
         // execute method testMethod
         Method m = o.getClass().getMethod("testMethod", new Class[] { });
         m.invoke(o, new Object[] { });
      }
      catch(Exception e) {
         System.out.println(e);
      }
   }
}

outputs:

testMethod() called!

Loading a class with the classloading mechanism in JDK1.2

When the JRE needs to load a new class, it consults following locations:

- bootstrap classes: the core API, rt.jar and i18n.jar
- installed extentions: all jars in lib/ext of JRE_HOME
- system classes: classes specified in the classpath
- download extensions: classes specified in the classpath header of installed extension jars, classpath jars, or previously downloaded download extensions.

1.2 has a delegation model for loading a class. Before loading a class with the current class loader, it is first delegated to the parent to check whether it can be loaded from there. For example, you could define your own package java.util and create a class Vector. Your class would be in the classpath and part of the system class loader, but this one delegates the request first to its parent, the bootstrap class loader which finds the class and loads it from there. This prevents a user from overriding security restrictions by replacing a class in the core API by an own version of the class.

You can create your own class loader by extending from java.lang.ClassLoader and you can specify a parent class loader. If you don’t specify the parent (null), then the system class loader will be its parent.

Compile Java contained in a String

A bit of hacking around lead to the following example. Create an instance of InMemorySourceCompiler and pass it the name of the program and the source code as a String. Any suggestions/improvements are appreciated as a comment to this answer.

The following example creates a JFrame that contains the output of the source.

Main.java:

import java.lang.reflect.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.*;
import java.util.*;
import java.io.*;
  
import sun.tools.javac.*;  
import sun.tools.java.*;
   
public class Main extends JFrame
{
   public Main(String s) {
      getContentPane().add(new JTextArea(s, 3, 50));
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
  
   public static void main(String args[]) throws Exception
   {
      // Save all data written to System.out to a byte array and display in frame
      PrintStream ps = System.out;
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      System.setOut(new PrintStream(baos));
 
      InMemorySourceCompiler imsCompiler = new InMemorySourceCompiler("Test",
          "public class Test {" +
          "   public static void main(String args[]) {" +
          "      System.out.println("Output of program:");" +
          "      for (int i=0; i<10; i++) {" +
          "         System.out.println(i);" +
          "      }" +
          "      System.out.println("End of output.");" + 
          "   }" +
          "}");
      imsCompiler.executeMain();
 
      byte[] b = baos.toByteArray();
 
      System.setOut(ps);
 
      String s = new String(b);
 
      Main main = new Main(s);
      main.setSize(200, 230);
      main.setVisible(true);  
   }
}
       
class InMemorySourceCompiler {
   protected String name;
   protected String source;
   protected Class compiledClass;
  
   public InMemorySourceCompiler(String name, String source) throws Exception {
      this.name = name;
      this.source = source;
      loadClass();
   }
 
   protected void loadClass() throws Exception {
      ClassPath cp = new ClassPath(System.getProperty("java.class.path"));
      OutputStream os = System.out;
      BatchEnvironment be = new BatchEnvironment(os, cp);
      be.flags = 0x41004;
      be.majorVersion = 45;
      be.minorVersion = 3;
      be.covFile = null;
      be.setCharacterEncoding(null);
 
      be.parseFile(new InMemorySourceClassFile(name+".java", source));
 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(4096);
 
      be.flushErrors();
      Vector v = new Vector();
 
      for (Enumeration enum = be.getClasses(); enum.hasMoreElements();) {
         v.addElement(enum.nextElement());
      }
 
      for (int i=0; i<v.size(); i++) {
         ClassDeclaration cd = (ClassDeclaration) v.elementAt(i);
         Object object = cd.getClassDefinition(be);
 
         if (object instanceof SourceClass) {
            SourceClass sourceclass = (SourceClass) object;
            cd.setDefinition(sourceclass, 5);
            SourceClass sourceclass1 = (SourceClass) object;
            baos.reset();
            sourceclass.compile(baos);
         }
         else if (object instanceof BinaryClass) {
            BinaryClass binaryclass = (BinaryClass) object;
            binaryclass.write(be, baos);
         }
         byte[] b = baos.toByteArray();
 
         InMemorySourceCompilerClassLoader myClassLoader = new InMemorySourceCompilerClassLoader();
         compiledClass = myClassLoader.getClassFromBytes(name, b);
      }
   }
 
   public void executeMain() throws Exception {
      Method m = compiledClass.getMethod("main", new Class[]{ String[].class });
      m.invoke(null, new Object[]{null});
   }
 
   static class InMemorySourceCompilerClassLoader extends ClassLoader
   {
      public Class getClassFromBytes(String name, byte[] b) {
         return defineClass(name, b, 0, b.length);
      }
   }
}
 
class InMemorySourceClassFile extends ClassFile
{
   private String filename;
   private String text;
 
   public InMemorySourceClassFile(String filename, String text) {
      super(new File(filename));
      this.filename = filename;
      this.text = text;
   }
 
   public String getAbsoluteName() {
      return filename;
   }
 
   public boolean exists() {
      return true;
   }
 
   public InputStream getInputStream() {
      return new StringBufferInputStream(text);
   }
 
   public String getName() {
      return filename;
   }
 
   public String getPath() {
      return "";
   }
 
   public boolean isDirectory() {
      return false;
   }
 
   public boolean isZipped() {
      return false;
   }
  
   public long lastModified() {
      return new Date().getTime();
   }
 
   public long length() {
      return text.length();
   }
 
   public String toString() {
      return filename;
   }
}

Using runFinalizersOnExit

If an object cannot be accessed anymore, it is ready for garbage collection. Before the memory is labeled free, the VM will call the object’s method finalize in which you can clean up resources. However, it is possible that the GC may never run (for example, there’s always enough memory). As a design guideline, you should not free up any memory or release database connections inside your finalize method, as you don’t have any control over when it will be invoked. Instead, use a custom cleanup method that is explicitely called when the object is no longer needed.

runFinalizersOnExit specifies that finalize methods will be invoked when the application exits.

Eg. run this example, uncomment and run it again:

public class Main {
   public static final void main(String[] args) {
      //System.runFinalizersOnExit(true); 
      new Main();
   }
 
   protected void finalize() {
      System.out.println("Main object finalized");
   }
}

Since JDK1.2, runFinalizersOnExit has been deprecated. From the API: “This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.” Check out http://java.sun.com/products/jdk/1.2/docs/guide/misc/threadPrimitiveDeprecation.html for more information on Sun’s view on this issue.

For more information, I wrote to Hans Boehm, an expert on Runtime issues. Here’s what he’s got to say:


Disclaimer: I generally don’t agree with the Java designers on the details of the finalization mechanism. Thus you shouldn’t take this to be authoritative.

My impression is that there are actually two issues. Sun’s documentation implies that they were worried about synchronization issues. What happens if a thread is stuck holding the lock on A, a finalizer needs the lock on A, and if you’ve requested that finalizers be run on exit. You can’t exit?

I have a more fundamental problem with it. It makes it impossible to rely on any finalizer ordering, which I claim makes it impossible ti write reliable nontrivial finalizers. Let’s say that A’s finalizer needs access to object B, which is also finalizable. To make this concrete, let’s say that B actually holds a handle to some object C manipulated by JNI native code, and B’s finalizer explicitly deallocates C with a JNI call. Thus if A accesses B after it is finalized, B will try to follow the dangling native pointer to C. This arises for example if A somehow buffers requests to B, and has to flush them when it’s finalized.

This is somewhat inconvenient with Java finalizers, but it’s not too bad. A needs to ensure that a pointer to B is kept in some static location, so that B doesn’t get finalized first. When A’s finalizer is run, it clears the static pointer to B, readying B for finalization.

But this break with runFinalizersOnExit! At exit, finalizers to statically accessible objects have to be run. A and B may both be accessible, and the runtime has no way to tell which finalizer should be run first. Thus there is no way to prevent the dangling native pointer dereference.

In general with runFinalizersOnExit, you can’t assume that when a finalizer is run, method calls on other objects (or static method calls) are safe, since any other object may have previously been finalized. Presumably parts of the runtime/standard library may also already be finalized. Thus it’s not clear to me that you can really safely do anything useful in a finalizer. Certainly runFinalizersOnExit will break code not designed to run with it.

Hans

What is a type descriptor?

It is a unique string that represents the class. For reference types, you can find out the type descriptor of a class by calling getClass on an instance and getName. Primitive types have “hard-coded” type descriptors according to the following table:

   boolean		Z
   byte			B
   char			C
   double		D
   float		F
   int			I
   long 		J
   short		S

The type descriptor of an array is [ for each dimension. So an array of int[][] will have a type descriptor [[I.

Main.java:

public class Main {
   public static void main(String args[]) throws Exception {

      int [][]array = new int[10][10];
      String s = "Hello, world!";
      A a = new A();    
      
      System.out.println(double.class.getName());
      System.out.println(array.getClass().getName());
      System.out.println(s.getClass().getName());
      System.out.println(a.getClass().getName());
      System.out.println(A.InnerA.class.getName());
      System.out.println(A.InnerA.InnerB.class.getName());
   }
}
 
class A 
{
   public class InnerA { 
      public class InnerB {
      }
   }
}

outputs:

double
[[I
java.lang.String
A
A$InnerA
A$InnerA$InnerB

Example of using clone()

Implement the Cloneable interface and call super.clone() if to make a bit-by-bit shallow copy. A shallow copy implies that only the references are duplicated in the new object and not the referents. This means that changing a referent in your original object has also an effect on the destination object. To prevent this from happening, you need to make a deep copy, that is manually creating duplicates for the members you don’t want to have shared. If all of your classes implement the Serializable marker interface, you can also make a deep copy by serializing using ObjectOutputStream and deserialize it using ObjectInputStream.
Look what happens in the two following examples.

Shallow copy

Main.java:

public class Main {
   public static void main(String args[]) {
      A a1 = new A();            // create an instance of A
      A a2 = (A) a1.clone();     // shallow-copy clone
 
      a1.sb.append(", world!");  // change the stringbuffer member of the first object
 
      System.out.println(a1);
      System.out.println(a2);    // not that the second object has also changed!
   }
}
 
class A implements Cloneable
{
   public StringBuffer sb = new StringBuffer("Hello");
 
   public String toString() {
      return sb.toString();
   }
 
   public Object clone() {
      try {
         return super.clone();
      } 
      catch(CloneNotSupportedException e) { }
 
      return null;
   }
}

outputs:

Hello, world!
Hello, world!

Deep copy

Main.java:

public class Main {
   public static void main(String args[]) {
      A a1 = new A();            // create an instance of A
      A a2 = (A) a1.clone();     // deep-copy clone
 
      a1.sb.append(", world!");  // change the stringbuffer member of the first object
      System.out.println(a1);
      System.out.println(a2);    // not that the second object has not changed now!
   }
}
 
class A implements Cloneable
{
   public StringBuffer sb = new StringBuffer("Hello");
 
   public String toString() {
      return sb.toString();
   }
 
   public Object clone() {
      try {
         A a = (A) super.clone();
         a.sb = new StringBuffer(sb.toString());
         return a;
      } 
      catch(CloneNotSupportedException e) { }
 
      return null;
   }
}

outputs:

Hello, world!
Hello

For more information on cloning an on whether you should catch the CloneNotSupportedException or specify a throws clause, see the link below.

Who is calling a method

Main.java:

import java.io.*;
 
public class Main
{
   public static void main(String []args) {
      test();
   }
 
   public static void test() {
      System.out.println("Method that called me: " + FlowInspector.getCallingMethod());
      new Main().new Inner().innerTest();
   }
 
   class Inner {
      public void innerTest() {
         System.out.println("Method that called me: " + FlowInspector.getCallingMethod());
      }
   }
}

FlowInspector.java:

public class FlowInspector
{
   public static String getCallingMethod() {
      try {
         StringWriter sw = new StringWriter();
         (new Exception()).printStackTrace(new PrintWriter(sw));
         StringReader sr = new StringReader(sw.getBuffer().toString());
         BufferedReader br = new BufferedReader(sr);
         br.readLine();
         br.readLine();
         br.readLine(); 
         String line = br.readLine();
         line = line.trim().substring(3);
         line = line.substring(0, line.indexOf('('));
 
         return line;
      } catch (Exception e) {
         e.printStackTrace();
      }
 
      return null;
   }
}

Running Main yields:

Method that called me: Main.main
Method that called me: Main.test