Getting the size of an object

Java does not know a sizeof operator as C++ does. But you may try something like getting the amount of free memory through the method freeMemory() in the Runtime class:

public class MyObject
{
   private int a[] = new int[1000];
  
   public static void main(String []args) {
      long fmstart = Runtime.getRuntime().freeMemory();
      Object o = new MyObject();
      long fmend = Runtime.getRuntime().freeMemory();
 
      System.out.println("Size of a MyObject object = " + (fmstart - fmend));
   }
}

You can’t rely on this code because you do not have control over the Garbage Collector thread that makes the amount of free memory fluctuate.
Another trick is to serialize the state of the object you want the size of and deduct information from that.

But think again, do you really need the capability of knowing the exact number of bytes of an Object? Probably not.

Cost of invoking a method through reflection

First of all, if that method takes a long time to execute, the overhead of invoking it is insignificant.

This example program shows some performance differences in milliseconds.
- normal: execute a method normally
- same: execute a method through reflection, but use the same method instance
- diff: execute a method through reflection, but do a method lookup inside the loop

It turns out that looking up the method is rather expensive but invocation is fairly cheap.

Main.java:

import java.lang.reflect.*;
 
public class Main {
   public static void main(String args[]) throws Exception {
      Main main = new Main();
 
      System.out.println("#tNormaltSametDiffn");
      for (int i=1; i<1048577; i*=2) { 
         long time1 = main.performNormalCalls(i);
         long time2 = main.performSameReflectiveCalls(i);
         long time3 = main.performDiffReflectiveCalls(i);
 
         System.out.println(i + "t" + time1 + "t" + time2 + "t" + time3);
      }
   }
 
   public long performNormalCalls(int n) throws Exception {
      long start = System.currentTimeMillis();
      for (int i=0; i<n; i++) {
         test();
      }
      long end = System.currentTimeMillis();
 
      return (end - start);
   }
 
   public long performSameReflectiveCalls(int n) throws Exception {
      long start = System.currentTimeMillis();
      Method m = Main.class.getMethod("test", null);
      for (int i=0; i<n; i++) {
         m.invoke(this, null);
      }
      long end = System.currentTimeMillis();
 
      return (end - start);
   }
 
   public long performDiffReflectiveCalls(int n) throws Exception {
      long start = System.currentTimeMillis();
      for (int i=0; i<n; i++) {
         Method m = Main.class.getMethod("test", null);
         m.invoke(this, null);
      }
      long end = System.currentTimeMillis();
 
      return (end - start);
   }
 
   public void test() { }
}

outputs:

#	Normal	Same	Diff
 
1	0	0	0
2	0	0	0
4	0	0	0
8	0	0	0
16	0	0	0
32	0	0	0
64	0	0	0
128	0	0	0
256	0	0	0
512	0	0	0
1024	0	0	50
2048	0	0	60
4096	0	0	160
8192	0	60	220
16384	0	50	550
32768	0	60	990
65536	0	50	2030
131072	0	170	4010
262144	0	330	7800
524288	0	710	15540
1048576	60	1430	31090

Creating an auto-complete JComboBox

Main.java:

import javax.swing.plaf.basic.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
 
      String[] elements = new String[] { "arthur", "brian", "chet", "danny", "dave",  
                                         "don", "edmond", "eddy", "glen", "gregory", "john",
                                         "ken", "malcolm", "pete", "stephanie", "yvonne" };
 
      JComboBox comboBox = new AutoCompleteComboBox(elements);
      getContentPane().add(comboBox);
   }
      
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}
 
class AutoCompleteComboBox extends JComboBox
{
   public int caretPos=0;
   public JTextField inputField=null;
 
   public AutoCompleteComboBox(final Object elements[]) {
      super(elements);
      setEditor(new BasicComboBoxEditor());
      setEditable(true);
   }
 
   public void setSelectedIndex(int index) {
      super.setSelectedIndex(index);
 
      inputField.setText(getItemAt(index).toString());
      inputField.setSelectionEnd(caretPos + tf.getText().length());
      inputField.moveCaretPosition(caretPos);
   }
 
   public void setEditor(ComboBoxEditor editor) {
      super.setEditor(editor);
      if (editor.getEditorComponent() instanceof JTextField) {
         inputField = (JTextField) editor.getEditorComponent();
 
         inputField.addKeyListener(new KeyAdapter() {
            public void keyReleased( KeyEvent ev ) {
               char key=ev.getKeyChar();
               if (! (Character.isLetterOrDigit(key) || Character.isSpaceChar(key) )) return;
 
               caretPos=inputField.getCaretPosition();
               String text="";
               try {
                  text=inputField.getText(0, caretPos);
               }
               catch (javax.swing.text.BadLocationException e) {
                  e.printStackTrace();
               }
 
               for (int i=0; i<getItemCount(); i++) {
                  String element = (String) getItemAt(i);
                  if (element.startsWith(text)) {
                     setSelectedIndex(i);
                     return;
                  }
               }
            }
         });
      }
   }
}

Rounding down a float or a double

Use the floor method in the Math class. It rounds down to the next lower integer:

import java.math.*;
                           
public class Main 
{  
   public static void main(String args[]) throws Exception {
      double d1 = 1.3, 
             d2 = 1.8,
             d3 = -1.3, 
             d4 = -1.8;
 
      System.out.println(Math.floor(d1));
      System.out.println(Math.floor(d2));
      System.out.println(Math.floor(d3));
      System.out.println(Math.floor(d4));
   }
}

outputs:

1.0
1.0
-2.0
-2.0

Using BigDecimals

As opposed to float or double, a BigDecimal allows you to store arbitrary precision signed decimal numbers.

Here’s a simple example that creates a BigDecimal.

Main.java:

import java.math.*;
import java.util.*;
 
public class Main {
   public static void main(String args[]) {
      BigDecimal bd1 = new BigDecimal(createLongDecimal());
      BigDecimal bd2 = new BigDecimal(createLongDecimal());
 
      BigDecimal total = bd1.add(bd2);
 
      System.out.println("  " + bd1);
      System.out.println("+ " + bd2);
      System.out.println("= " + total);
   }
 
   public static String createLongDecimal() {
      Random r = new Random();
      StringBuffer total = new StringBuffer();
      for (int i=0; i<15; i++) {
         total.append(Math.abs(r.nextInt()));
         if (i == 10) total.append('.');
      }
  
      return total.toString();
   }
}

outputs:

  720503977823516025489207568136178482425783671110507142011860888752101
66134093438986271599747576765999033.18149285701107649443668155859929740
+ 720503977823516025489207568136178482425783671110507142011860888752101
66134093438986271599747576765999033.18149285701107649443668155859929740
= 144100795564703205097841513627235696485156734222101428402372177750420
332268186877972543199495153531998066.36298571402215298887336311719859480

There are other ways to create a BigDecimal, a constructor that allows you to pass a double and one with a BigInteger.
The constructor that accepts a double is “somewhat inpredictable”, according to the API.
Consider the following program.

Main.java:

import java.math.*;
  
public class Main {
   public static void main(String args[]) {
      BigDecimal bd1 = new BigDecimal(.1);
 
      System.out.println(bd1);
   } 
}

outputs:

0.1000000000000000055511151231257827021181583404541015625

Sending email through SMTP with Java

The optional package JavaMail allows you to do this. I’ve devoted a separate category that tells you where you can d/l it plus some tutorials and links.

This following class doesn’t use JavaMail, but it uses SMTP commands to allow to send a simple mail. To run it, you need to specify an SMTP server, a from and to email address, subject and body.

Main.java:

import java.io.*; 
 
public class Main {
   public static void main(String[] args) {
      if (args.length != 5) {
         System.err.println("usage: java Main <SMTP server> <from> <to> " + 
                            "<subject> <body>");
         System.exit(1);
      }
  
      try {
         SMTPEmail smtp = new SMTPEmail(args[0]);
         smtp.sendMail(args[1], args[2], args[3], args[4]);
      }
      catch(IOException e) {
         e.printStackTrace();
      }           
   }
}

SMTPEmail.java:

import java.io.*;
import java.net.*;
 
public class SMTPEmail
{
    private Socket smtpSocket;
    private BufferedReader br;
    private BufferedWriter bw;
       
    private String smtpHost;
    
    public SMTPEmail(String smtpHost) throws IOException {
        this.smtpHost = smtpHost;
    }
    
    public void connect() throws IOException {
        smtpSocket = new Socket(smtpHost, 25);
        br = new BufferedReader(new InputStreamReader(smtpSocket.getInputStream()));
        bw = new BufferedWriter(new OutputStreamWriter(smtpSocket.getOutputStream()));
    }
    
    private void disconnect() throws IOException {
        smtpSocket.close();
    }
    
    private void send(String str) throws IOException {
        System.out.println("Sending: " + str);
        bw.write(str + "rn");
        bw.flush();
    }
    
    private String receive() throws IOException {
        String str = br.readLine();
        System.out.println("Receiving: " + str);
        return str;
    }
    
    public void sendMail(String fromAddress, String toAddress, String subject, 
                         String body) throws IOException {
        connect();
        String whoami = InetAddress.getLocalHost().getHostName();
        send("HELO " + whoami);
        receive();
        send("MAIL FROM: <" + fromAddress + "> ");
        receive();
        send("RCPT TO: <" + toAddress + "> ");
        receive();
        send("DATA");
        receive();
        send("TO: " + toAddress);
        send("FROM: " + fromAddress);
        send("SUBJECT: " + subject + "rn");
        send(body);
        send("rn.rn");
        receive();
        send("QUIT");
        disconnect();
    }
}

Downloading a secure page (HTTPS) with Java

If you try to get data from an HTTPS-enabled page, you will get a MalformedURLException, as shown in following example:

Main.java:

import java.net.*;
import java.io.*;
 
public class Main {
   public static void main(String[] args) throws Exception {
      URL url = new URL("https://www.sun.com");
      BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
      String line;
      
      while ((line = br.readLine()) != null) {
         System.out.println(line);
      }
  
      br.close();
   }
}

outputs:

C:>java Main
Exception in thread "main" java.net.MalformedURLException: unknown protocol: https
        at java.net.URL.<init>(URL.java:497)
        at java.net.URL.<init>(URL.java:364)
        at java.net.URL.<init>(URL.java:308)
        at Main.main(Main.java, Compiled Code)

This is because Sun has no implementation for the HTTPS protocol in their core libraries. However, they created an reference implementation called Java Secure Socket Extension (JSSE) available as seperate download at http://java.sun.com/products/jsse.

Include jcert.jar, jnet.jar and jsse.jar in your classpath and add the following two lines of code to the previous program:

      System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); 
      Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

Here’s the updated example that works:

import java.security.*;
import java.net.*;
import java.io.*;
 
public class Main {
   public static void main(String[] args) throws Exception {
      // create a new protocol handler
      System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
 
      // protocol handler uses this security provider
      Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
  
      URL url = new URL("https://www.sun.com");
      BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
      String line;
      
      while ((line = br.readLine()) != null) {
         System.out.println(line);
      }
 
      br.close();
   }
}

What is PKCS#5 padding?

Ciphers process data in blocks, for example 8 byte blocks. If the length of the data that you want to encrypt is not evenly divisible by the blocksize that your encryption algorithm uses, the data needs to be padded. PKCS#5 is one way of padding. It appends to every message a block of data varying from 1 to 8 bytes where each bytes contain the number of bytes that are padded.

For instance, if the length of the data is 10, then 6 bytes need to be padded. The last block of 8 bytes will look like this:

 +---+---+---+---+---+---+---+---+
 | D | D | 6 | 6 | 6 | 6 | 6 | 6 |
 +---+---+---+---+---+---+---+---+

If the length of your data happens to be evenly divisible by 8, an extra 8 bytes will be added looking like this:

 +---+---+---+---+---+---+---+---+
 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 |
 +---+---+---+---+---+---+---+---+

This is because PKCS5Padding always assumes there is a pad.