FAQ on Advanced Topics by Roseanne Zhang
?????????????????????????????????????????????http://bobcat.webappcabaret.net/javachina/faq/a_01.htm
The questions and answers here are my selective postings on jGuru, JavaRanch, ChinaJavaWorld in order to answer others' questions. After a while of doing this, I realized that a lot of similar questions are being asked again and again.
The purpose of creating this page is to let people in the future have a place to look for answers. People don't need to answer the same question again and again.
Software reusability is extremely important. OO analysis, design, and programming are invented for this purposes. So does the component-based software. Design patterns are discovered for reusing other's design ideas. This page is created for reusing my own answers. Hopefully, this page will make your learning process a little easier.
We all work together to make a difference!
Swing, AWT, etc.
Also, on some Unix systems without GUI support, Swing will not work since the OS does not provide the native peers. Of course, it will work on these Unix system such as X-windows, Linux, Mac OS X, and ... Unless, you want to do a lot of extra work (such as an emulator), and then that should credit to you, not Swing any more...
Linked from , Mixing Heavy and Light Components
one of the primary design goals for Swing was that it be based on AWT architecture.
Read the fine prints, please! I'm serious! People tend to read what they like or what they think to read. Sun actually prefers you read that way too. Swing is not a good GUI product, it never was, and it will never be. Sorry to tell the truth. A story of Creative writer
Read Graphic Java Master the JFC, 3rd edition, by David M. Geary p6 Nearlyall Swing components are lightweight. The only exceptions are Swing's top-level containers: frames, applets, windows, and dialogs. Because lightweight components are rendered in their container's window instead of a window of their own, lightweights must ultimately
be contained in a heavy weight container...




My translation would be "Something must be impossible to him/her."
Java API doc - Provides a set of "lightweight" (all-Java language) components that, to the maximum degree possible, work the same on all platforms.
import java.awt.event.*; import java.awt.*; import javax.swing.*; public class EventTest extends JFrame implements ActionListener{ private JButton bn1, bn2, bn3; public EventTest(){ super("Event Test"); Container container = getContentPane(); container.setLayout(new FlowLayout()); bn1 = new JButton("JButton 1"); bn2 = new JButton("JButton 2"); bn3 = new JButton("JButton 3"); bn1.addActionListener(this); bn2.addActionListener(this); bn3.addActionListener(this); container.add(bn1); container.add(bn2); container.add(bn3); setLocation(400, 300); pack(); setVisible(true); } public static void main(String[] args) { EventTest eventTest = new EventTest(); eventTest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void actionPerformed(ActionEvent event){ Object o = event.getSource(); if (o instanceof JButton) { JButton bn = (JButton)o; JOptionPane.showMessageDialog(this, bn.getText() + " clicked"); } } }
import javax.swing.*; import java.awt.event.*; class LFTest { JFrame myfrm; JTextField txtTest; JPanel panel; JComboBox cmbTest; String[] lfstrs = {"com.sun.java.swing.plaf.motif.MotifLookAndFeel", "javax.swing.plaf.metal.MetalLookAndFeel", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"}; String lfs; public static void main(String[] args) { new LFTest(); } LFTest() { try { lfs = UIManager.getSystemLookAndFeelClassName(); UIManager.setLookAndFeel(lfs); myfrm=new JFrame("Test For Look and Feel "); txtTest=new JTextField("We are changing look and feel by selecting in the combobox"); cmbTest=new JComboBox(lfstrs); cmbTest.addItemListener(new MyItemListener()); cmbTest.setSelectedItem(lfs); panel=new JPanel(); panel.add(txtTest); panel.add(cmbTest); myfrm.getContentPane().add(panel); myfrm.pack(); myfrm.setVisible(true); myfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } catch (Exception e) { System.err.println("Could not switch to look and feel " + lfs); } } class MyItemListener implements ItemListener { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { try { lfs = (String)e.getItem(); UIManager.setLookAndFeel(lfs); SwingUtilities.updateComponentTreeUI(myfrm); myfrm.pack(); } catch (Exception ex) { } } } } }
TableColumnModel colMdl = jtbl.getColumnModel(); // Hide password column, the column still in the tablemodel colMdl.removeColumn(colMdl.getColumn(2));
import java.awt.*; import java.awt.image.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class BG3 extends JFrame { private int w = 800; private int h = 600; MyCanvas canvas; public BG3() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container container = getContentPane(); canvas = new MyCanvas(); container.add(canvas); setSize(w, h); setVisible(true); } public static void main(String arg[]) { new BG3(); } } class MyCanvas extends Canvas { String fName = "Flowers006.JPG"; Image displayImage = null; MyCanvas() { displayImage = Toolkit.getDefaultToolkit().getImage(fName); MediaTracker mt = new MediaTracker(this); mt.addImage(displayImage, 1); try { mt.waitForAll(); } catch (Exception e) { System.out.println("Exception while loading."); } if (displayImage.getWidth(this) == -1) { System.out.println("File " + fName + " does not exist!"); System.exit(0); } } public void paint(Graphics g) { g.drawImage(displayImage, 0, 0, getWidth(), getHeight(), this); } }
import javax.swing.*; import java.awt.*; import java.util.*; public class JListWithImages extends JList { public JListWithImages() { setCellRenderer(new CustListCellRenderer()); } public static void main(String[] args) { JFrame frame = new JFrame("JList with Images Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pnl = new JPanel(); Vector vector = new Vector(); ImageIcon img1 = new ImageIcon("res/img1.gif"); ImageIcon img2 = new ImageIcon("res/img2.gif"); JLabel lbl1 = new JLabel("selection 1", img1, JLabel.LEFT); JLabel lbl2 = new JLabel("selection 2", img2, JLabel.LEFT); vector.addElement(lbl1); vector.addElement(lbl2); JListWithImages lstWImgs = new JListWithImages(); lstWImgs.setListData(vector); JScrollPane s = new JScrollPane(lstWImgs); s.setPreferredSize(new Dimension(200, (img1.getIconHeight()+2)*vector.size())); pnl.add(new JLabel("List with Images: ", JLabel.RIGHT)); pnl.add(s); frame.getContentPane().add(pnl); frame.pack(); frame.setVisible(true); } class CustListCellRenderer implements ListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel lbl = (JLabel)value; lbl.setOpaque(true); lbl.setBackground(isSelected ? Color.black : Color.white); lbl.setForeground(isSelected ? Color.white : Color.black); return lbl; } } }
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.*; public class SimBrower extends JFrame implements ActionListener{ JEditorPane edtPane = new JEditorPane(); JLabel lbl = new JLabel("Type URL:", JLabel.RIGHT); String samurl = "http://java.sun.com/docs/books/tutorial/uiswing/components/example-1dot4/TextSamplerDemoHelp.html"; public SimBrower(String title) { super(title); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel pnl = new JPanel(); pnl.add(lbl); JTextField urlFld = new JTextField(60); lbl.setLabelFor(urlFld); urlFld.addActionListener(this); urlFld.setActionCommand("url"); urlFld.setText(samurl); pnl.add(urlFld); getContentPane().add(pnl, BorderLayout.NORTH); setEditorPane(samurl); JScrollPane scrPane = new JScrollPane(edtPane); scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); getContentPane().add(scrPane); setSize(800, 600); setVisible(true); } public void actionPerformed(ActionEvent evt) { String s = evt.getActionCommand( ); if (s.equals("url")) { JTextField src = (JTextField)evt.getSource(); String surl = src.getText(); setEditorPane(surl); } } private void setEditorPane(String s) { try { URL url = new URL(s); edtPane.setPage(url); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { SimBrower frm = new SimBrower("Simple Brower"); } }
Applets, Servlets, etc.

Object o;
which is truely local. The Java object created local is equivalent to c++, Object* p = new Object();
which can be used outside of the local range.
If you are only developing and display on your local machine, it is easy. The followings would be I do in that order.
- Refresh, of course
- Go to IE explorer properties dialog, delete all offline files, your problem is solved.
- Temporaly rename your page to something else, and access the "new" page.
- Shutdown my website for a minute, and access it, the proxy will give me 404. Then restart.
The basic OO concept: let everyone take care oneself. Let God take care of everyone!!!!
Immutable, etc.

----quotation from JLS 10.9 I think as long as the data member (contents of the class) cannot be changed, the class is immutable. If the data member refers to something else, the change of something else does not necessary mean the class is mutable, since they are NOT contents of the class, only their references are. This is similar to the difference between aggregation and composition in UML (or OO). The object is destroyed; the composition parts disappear too. The aggregation can be still there. The immutable object can be GC-ed, but the something-else which its data member referring to can be still there. This might not be something in the mind of Java creators. Who knows? They might change their minds too. The Human Factors...A real world immutable class example: A printed book sits on a shelf of a library can reasonably be considered as an immutable class (object). It has references to White House, US. and some websites. The references in the book will never change, but the president sitting there and the contents of the websites will constantly change, as we all know...
Flaming discusion on final vs. immutableMake sure you read the above.

- Does immutable made String class more efficient?
No, Java String class is most famous for its inefficiency. All major coding guidelines (including Sun's) will advise use less String class, and use StringBuffer instead. Since whenever you need do something on it, you actually need to build a new one, and put the old one for GC. String literal pooling is just a small remedy for a big disease. Read here for some of the ugliness of Java (String class included): The Java IAQ:Infrequently Answered Questions, read question 12, please. An empty new String() takes 40 bytes!!! That is why C# puts String as a value-type. - How about other wrapper classes such as Integer or Boolean?
See Java.lang.reflect package, immutability of those classes is extremely critical for Java reflection to work safely and correctly. - Are Boolean/Integer/Long/etc. classes basic building blocks of Java Language?
No, they are not. boolean/int/long/etc. are!! If Boolean/Integer/Long/etc. were the basic building blocks of Java language, Java would be dead by now!!! They partially contribute to the slowness of using reflection.
JavaMail, etc.
import sun.net.smtp.SmtpClient; import java.io.PrintStream; public class Mail { public static void main (String args[]) throws Exception { String host = "mail.localdomain.com"; // replace localdomain with yours String from = "aa@bb.com"; // does not matter String to = "javachina@hotmail.com"; // a real mailing address SmtpClient smtp = new SmtpClient(host); smtp.from(from); smtp.to(to); PrintStream out = smtp.startMessage(); out.println("To: " + to); out.println("Subject: Hello SmtpClient"); // blank line between headers and message out.println(); out.println("This is a test message."); out.flush(); out.close(); smtp.closeServer(); } }
Security, Cryptography, etc.
- If the encryption/decryption are done by the same party, symmetric algorithm is the way to go. Blowfish is a new and better symmetric encryption algorithm. DES is another one... I used Blowfish encryption; our product has just shipped to Disney.
- RSA is for encrypting by one party and decrypting by another party. RSA or other Public/Private Key pair system (e.g. D-H Public-Key Directory) solved the famous key transportation problem. Read a very good introductory from here: Introduction To Cryptography
- MD5, SHA or other one-way digest encryption algorithm is for encrypting password, which means you never want to decrypt it back. I used it on our project team login page for a little more than a year now...Different encryption algorithms solve different problems and are used for different purposes...
- One thing worths mention is MD5/SHA is not secure any more, thanks the Chinese lady, great methimatician Wang Xiaoyun and her team. You can attach the MD5 encrypted password to get access to the protected database etc. It is hard, but not practically impossible any more.
- You can find the article from here

- Small application, mobile games, etc. Obfuscation is absolutely necessary! Otherwise, you have no way to sell your software! You are commiting suicide. You ship one out, everyone gets your source code, everybody can modify it a little bit, and says this is mine. You need not only to obfuscate the jar file, but also all resources, and all the images, even all the text. You try to play as many tricks on the software as possible. Can it be reverse engineered? Yes, it still can be. However, you waste too much time to do that, you cost more than you develop a new software by yourself.
- Huge application, extremely complicated application, there is no need to obfuscate it. It is because reverse engineering effort costs too much, and gain almost nothing. We developed a $20M worth software in Java, majorly in math, a huge company used $0.5M for just testing it, and got all our jars. We knew they wanted to steal our source code from the very beginning. However, we let them get the jars. They wasted their money, and got nothing. This company applied for bankrupcy protection recently.
- If your application size is in-between, not too big, not too small, make your best judgement, make your own decision.
- Should I still use SHA-1 or MD5 to encrypt my password. Answer is yes until you find a better way. It is much safer than clear text.
- Can it be reversed to original clear text? No, it is theoreticall impossible. Why?
- Any data can be encrypted to MD5, the set of original data is infinite large set.
- MD5 can be only 128 bits, or you make it even bigger, it is still a limited set.
- Therefore, different data can be encrypted to the same encryption.
- The crack is actually creating a data which will encrypted to the same value.
Zip, Unzip, etc.
// to upzip File file = new File(zipfilename); ZipFile zipFile = new ZipFile(file); Enumeration enum = zipFile.entries(); byte [] buf = new byte[1024]; while (enum.hasMoreElements()){ ZipEntry zipEntry = (ZipEntry) enum.nextElement(); // loop through each one // you work out the rest }
JDBC, etc.
Tutorials
Memory Leaks, GC, etc
Java does not have c/c++ meaning of memory leak, since GC.However, Java does have its own meaning of memory leak, which is memory use growing with loitering objects. In other words, programmer keeps more object references than they needed.
/* * an example in C++ */ void method1() { Object *p = new Object(); // a lot of code here //if you forgot this delete line, mem-leak happens delete p; } /** * an example in Java */ void method3() { Object o = new Object(); // a lot of code here, but don't attach or return o to some other place //it will not cause mem-leak if you don't put this line, //since GC will do it for you o = null; // not necessary, but nice to have } /** * another example in Java */ void method3(AnotherObject ao) { Object o = new Object(); // a lot of code here ao.afield = o; // a lot of code here too //it will cause mem-leak if you don't put this line, // even after the above process, object o is never been used again //since GC will not do it for you. ao keeps o's reference, //if you call this function many times with diferent ao, // you will get OutOfMemoryException. o = null; // necessary now }
Computer Algorithms
2) Make copy of each, O(n)
3) Sort both copy, O(n * lg n)
4) Compare each pair O(n)
Over all O(n * lg n)It is much better than nested loop, which is O(n*n). If the n = 13,000,000,000, use your calculator, you will see huge speed difference.


http://www.geocities.com/developergrp/Code/SortBy.htm
- DFS: Depth First Search algorithm for traversal a graph. Recursion and stack are used to do the job.
- BFS: Breadth First Search algorithm for traversal a graph. Using queue instead of stack.
- Tree is a special graph, a non-cyclic direct graph.
- You should not traverse the directory tree at all. What you only need is to display the top-level nodes and find out which directory is non-empty. If it is not empty, put a dummy node under it, to make that node display correctly. When user clicks it, load the real data on as-leaded bases.
- This is called Proxy Design Pattern; it saves your time and resources. Read GoF's book for details.
- I used working on millions history records tree in VC++. Should I traverse the entire tree, no matter DFS or BFS, my program would die, and I would have been fired. I used Proxy pattern, even I did not know the pattern name then. Open folder on demand. When user close a folder, I need to unload some tree nodes by choosing Least Recent Used (LRU) nodes and use a dummy nodes again to save system resources and memory. Never use Depth First Search (DFS) in GUI tree, please!
class TestRecursion{ public static void main(String args[]){ System.out.println(sum2(8000)); //OK System.out.println(sum1(8000)); //Stack Overflow } static long sum1(long a) { if (a == 1) return 1; return a + sum1(a - 1); } static long sum2(long a) { if (a == 1) return 1; return sum2(a - 1) + a; } }
What I did?
- Modified the code a little bit, I tried to make it more brief and symmetric. That is the code above.
- Compiled it and see the output error, reduced the recursion number to see the error disappeared. This proved the code is correct, but has problems.
- I used javap -c TestRecursion to disassembled the code. Saved the assembly code for sum1 and sum2 in 2 files.
- I used examdiff software to compare the assembly code of the two functions, and see the difference. The different parts are high-lighted with red lines in the following picture.
- Now, it is obvious what is wrong with sum1, since it put "a + ", it causes the int "a" is stored on the stack, which take memory. One int is almost nothing, but 8000 int(s) are enough to bring stack overflow much sooner than sum2, which add "a" after recursive calls of sum2.
- hat is it!!!
javap -c TestRecursion Compiled from "TestRecursion.java" class TestRecursion extends java.lang.Object{ TestRecursion(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc2_w #3; //long 8000l 6: invokestatic #5; //Method sum2:(J)J 9: invokevirtual #6; //Method java/io/PrintStream.println:(J)V 12: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 15: ldc2_w #3; //long 8000l 18: invokestatic #7; //Method sum1:(J)J 21: invokevirtual #6; //Method java/io/PrintStream.println:(J)V 24: return static long sum1(long); Code: 0: lload_0 1: lconst_1 2: lcmp 3: ifne 8 6: lconst_1 7: lreturn 8: lload_0 9: lload_0 10: lconst_1 11: lsub 12: invokestatic #7; //Method sum1:(J)J 15: ladd 16: lreturn static long sum2(long); Code: 0: lload_0 1: lconst_1 2: lcmp 3: ifne 8 6: lconst_1 7: lreturn 8: lload_0 9: lconst_1 10: lsub 11: invokestatic #5; //Method sum2:(J)J 14: lload_0 15: ladd 16: lreturnHere is the examdiff screen shot. Please pay attention to the underlined difference..

- Rehash, recalculate the hashCode according to certain rule, and store it in the new location. If the new location has also occupied by another object, rehash again?
- Make each storage unit has a grow-able bucket (linked-list, black-red tree, etc.). If you find the first one is not what you want, use equals() to compare to the next...
- ...
- O(average rehashing number)
- O(average bucket size) for linked-list
- O(log(average bucket size)) for black-red tree or other binary search tree

Since any Java class directly or indirectly extends Object, it does inherit the extra size of hashCode. You have no way to avoid it, no matter you need it or not. That is my point.
public class SelectionSort{ public static void sort(int[] a){ int temp; int j = 0; int minIx = 0; for (int i = 0; i < a.length; i++){ minIx = i; for(j = i+1; j < a.length; j++) { if (a[minIx] > a[j]) { minIx = j; } } temp = a[minIx]; a[minIx] = a[i]; a[i] = temp; } } public static void printArray(int[] a){ for(int i=0; i < a.length; i++){ System.out.print(a[i]); if (i < a.length-1) { System.out.print(", "); } else { System.out.println(); } } } public static void main(String[] args){ int[] a = {10, 35, 8, 6, 8, 89, 76, 76, 4, 90, 78}; sort(a); printArray(a); } }
Java and multi-platforms

I used to work in a place, our jars could build on windows or unix, and deployed to HP-UX, solaris, windows, or linux. The things I needed to take care were:
- Our native build, you all know, c/c++ code are platform dependent.
- Our batch files needed to have a Unix shell script version. See ant/tomcat bin directory for practical examples.
- Environment variable settings needed to be adjusted in each individual machine, let alone platforms. of cource!
- Choose a nearest mirror to download, it is an entire unix operating system, it is huge.
- Do not install at the same time as download.
- Use default option first, you can add on later when you need.
- Do keep your download directory carefully, do not change/delete the weird directory name!!! This will save you huge amount of time when you need add-ons.
- cygwin home page
Miscellaneous
System.setProperty("java.class.path", "yourNewClassPath");
to set it, and even use System.out.println(System.getProperty("java.class.path"));
to read it back. However, JVM will ignore them all together. After JVM started, the classpath cannot be changed, period.Then, how can I load classes not on my classpath? Try to use URLClassLoader to do the job. However, that is another big and important topic, which worth writing a chapter for it. There are many pitfalls and gotchas there, read Dr. Ted Neward's white pappers here When a static not a static?org.apache.tools.ant.taskdefs.Execute static java.util.Vector getProcEnvironment() //Find the list of environment variables for this process.You can either use it, or learn from it, since it is open source.

In java, programmers usually think the GC is responsible to deal with the alllocation of the memory. Officially, Java should not have memory leak. However, it is far from the truth. Java memory leak is actually unintentional retain of object references, which means the object is no longer needed, but still be referred somewhere. This kind of memory leak is much harder to detect.
Read here, it is the CTO of a tool JProbe: http://industry.java.sun.com/javaone/99/event/0,1768,618,00.html
What we can do? From my experience, we can do the followings:
- Recycle huge objects, do your own memory management. Pooling is one way to do it. Using an arrays to recycle them is another simple way, create new one only when the recycling array is empty. I used to do this in c around the x286 time.
/>
- When an object is not in use any more, explicitly set it to null. But this will depend on the conscious of your programmers.
- When you use tools (like JProbe or the BoundsChecker in the old days). Find the area which uses memory most, and refactor (redesign/code) that part.

class Book { private: Chapter chapter1, chapter2; Reference *pref1, *pref2; public: Book(); virtual ~Book(); void setReferences(Reference* pRef1, Reference* pRef2); // other stuff }
Runtime rt = Runtime.getRuntime(); Process ps = rt.exec("cmd /c \"start " + htmlfname + "\"");
From my practice and compare with VC++. When number of iterations is low, VC++ can be faster than Java. The problem to solve was SLDP 1+1 algorithm on a huge telephone network 610ms vs. 1085ms (Java). Please do not think it is a simple problem, believe me or not, the code written beofre me by someone else needed to run more than 12 hours. It is the power of a good algorithm!!!
When my code became much more complicated and number of iterations increases huge, Java can be much faster than VC++, 26s vs. 12s (Java). Both code uses the same algorithm, written by the same programmer, and I was much more proficient on VC++ than Java then, run on the same machine, and solve the same real world problem ( a huge telephone company network surviving and optimization 1 + 1 problem, including new optical line recommendation).
You might be wondering, why I wrote them twice in 2 different languages. That was a long story, and I'd better not to post it here.
For scientific calculation, the general opinion on speed seems:
Fortran > C > C++ > Java
However, on high iteration case, Java can be faster than C++.
Java > C++
JIT or HotSpot plays a beautiful role here.
#!/bin/bash -x searchfor=$1 for line in `find . -name "*.java"` do grep -n -H $searchfor $line done
import java.lang.reflect.Method; import java.lang.reflect.Field; class A { public static final String staticField = "this is the value of the staticField"; public String instanceField = "this is the value of the instanceField"; public static int aStaticMethod() { return 3; } public int aInstanceMethod() { return 4; } public int aInstanceMethodWithParams(int a, int b) { return a+b; } } public class ReflectionDemo { public static void main(String[] args) { try { // Get Class object Class cls = Class.forName("org.javachina.ex1.A"); // Get Fields Field sfld1 = cls.getField("staticField"); Field ifld2 = cls.getField("instanceField"); System.out.println(sfld1); System.out.println(ifld2); // Get Filed's values System.out.println(sfld1.get(null)); System.out.println(ifld2.get(new A())); // Get Methods System.out.println(cls.getMethod("aStaticMethod", null)); System.out.println(cls.getMethod("aInstanceMethod", null)); Class[] ary = new Class[]{int.class, int.class}; System.out.println(cls.getMethod("aInstanceMethodWithParams", ary)); // Get all declared Methods Method[] mary = cls.getDeclaredMethods(); for (int i=0; i<mary.length; i++) { System.out.println("here: " + mary[i]); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } }
import java.net.*; public class HostToIP { public static String fromHostToIP(String hostname) { String ipStr = ""; try { InetAddress addr = InetAddress.getByName(hostname); byte[] ipAddr = addr.getAddress(); for (int i = 0; i < ipAddr.length; i++) { if (i > 0) { ipStr += "."; } ipStr += ipAddr[i] & 0xFF; } } catch (UnknownHostException e) { e.printStackTrace(); } return ipStr; } public static void main(String[] args) { String hostName = "webappcabaret.net"; if (args.length > 0 && args[0].trim().length() > 0) { hostName = args[0]; } System.out.println(HostToIP.fromHostToIP(hostName)); } }