Sunteți pe pagina 1din 125

General Questions

1. What is Java?
A:

• Java is a beautiful island in Indonesia.


• Java is another name for coffee, since coffee produced in Java, Indonesia is good!
• Java is also a programming language was invented by Sun's programmers when
they drank too much coffee. The language was called Oak, but it had a
trademark conflict, then they renamed it as Jav

2. Is Java a pure OO language?


A: No, it is not.
neither are C++/C#/etc. SmallTalk is general considered as a pure OO language. In
SmallTalk, everything is an object, including int or even + sign. Java is one step more
close to SmallTalk than C++, but it is still not pure OO language. Why bother to discuss
this? Language is just a tool to get the job done. Choose one is better for your
job/business. If speed is absolutely critical to your application, use FORTRAN, c or
assembly. Burn your algorithm into the semiconductor chips would be a good choice too,
of course, if it is necessary! In some cases, OO is an obstacle. SmallTalk never becomes a
main stream programming language since it is too slow.

3. In what order should we get certified, Programmer, Developer, and Architect?


A:
Passing programmer's test will get you an interview, since others will consider you know
Java at least as a walking Java compiler, maybe more, like Tony.

Passing developer's test will prove that you can code in Java, if you are not programming
Java on your job yet. That is second to the real world job experience (psuedo-real-world,
I like the word!). If you don't have any real coding experience in Java, or do not have any
programming experience even in other languages, skip the developer's exam, and go
ahead to do the Architect test? I'll consider that is crazy!!!

If you are already coding in Java, go ahead to prepare for the architect exam. That may be
a reasonable choice. However, SCEA is not trivial either (3 parts test). SCJP is not a
prerequisite of SCEA.

Why a lot of people skipped the developer exam to go SCJA (the old one), since the old
one was just like SCJP, multi-choices only. If you did enough mocking exams, it was
relatively easy to pass. There was another factor that almost everyone got the same test.
Enough leaking made it even easier.

That might be one of the reasons why Sun changed the test to SCEA.
We have SCJD Study Group. If you pass the SCJP, you are welcome to join us!

4. How do I statr to learn programming?


A: Except reading, coding, Coding, CODING!

• Type! Do not copy/paste examples from the book!


• Modify! Let the example from book do different things!
• Write! Write something similar, but from scatch!
• Develop! Develop a new application.

Q. What software or books I should buy to prepare the test?


A:
My suggestion, don't buy any exam software. They don't help much IMHO.

But at least by one book, Bill Brogden's Exam Prep or Exam Cram will be my first
choice. (Bill did not pay me anything, BTW. Get Bruise Eckle's free book, "Thinking
In Java". If you can afford it, buy it. He did not pay me either. Learn how to use Sun's
"The Java Tutorial" on Line, please! I saw so many questions asked here, which could be
answered more precisely by a simple search of the free book from Sun.

Do free mocking exams or not free ones, when you get something wrong, read, code, test
back and forth until you thoroughly understand. You are not only preparing yourself for
the test, but also for your future interview and job. Read, Code, code, code, and test until
the Java concepts become yours.

Post a question somewhere to get answer from others when you really get stuck!

Free Java Books

Q. What to do when we see something ambiguous on the real test?


A:
If you think something on the test is ambiguous, mark the question; make the best guess
you can, finish the rest of the test. If you have time, go back to that question. It may not
be ambiguous anymore, and then choose the correct answer. Otherwise, keep your figure
crossed!

Do remember MARK any question in doubt. I lost some points since I did not mark, then
could not find that question to which I gave wrong answer any more.

But, who cares now?


Q. What do I need watch out for filling blank questions?
A:
Read questions very carefully; don't jump into conclusions. ONLY write exactly what is
asked for - no extra punctuation such as quotes. Some questions will give a list of words
you can pick from.

Don't add legs when you drawing a snake!

Q. Where can I get all the Sun's test information?


A:

• General: http://suned.sun.com/USA/certification/javamain.html
• SCJP: http://suned.sun.com/USA/certification/progdetails.html
• SCJD: http://suned.sun.com/USA/certification/devdetails.html
• SCJEA: http://suned.sun.com/USA/certification/archdetails.html

Q. Do I have a future if I learn Java by myself?


A:

1. I don't know how many of us learned Java not from ??. I guess, most of us are
from ??. At least, I learned C++, VB, VC++, Java, Perl, Shell Script, XML,
XSLT, etc. etc. from ??. Even I've taught others Java, C, Pascal.
2. Do I have a future if I learn Java by myself? I think this is a $64k question and the
answer depends on you!
o What is your definition and expectation of having a future.
o How many effort do you want to put in for your future.
o Some other factors, such as your personality, your learning style, your
luck, etc.....

Nobody can tell you what to do to get your ??, but you!! yourself!!!!

Language Fundamentals

Q. What are Java key words and reserved words? What are the differences?
A:
Key words are reserved words. but not vice versa. See Java Language Keywords for
details.

Q. What are Java key words this?


A:
this is a keyword used in Java/C++ code to refer the current instance object itself.

Q. What is reference in Java? Is is the same as pointer in C/C++?


A: In Java, reference is a typed named memory space which holds addrees of an Object
of that type.
It is called reference in Java, but called pointer in C/C++. The key differences between
C/C++ with Java on pointer/reference are:

• You cannot put your hands on an Object without through its reference in Java. In
C/C++, you can.
• In C/C++, you can do arithmetic on pointers, but you cannot do arithmetic on
references in Java.
• In C/C++, you can dereference a pointer, you cannot dereference a reference in
Java.
• In Java, all object are put on the heap only. In C/C++, you can put an
Objecty/struct onto the stack.
• In C/C++, you can cast pointer to an totally defferent type without compiler
errors. In Java, you cannot, Java is more strong typed language.
• In C/C++, pointer can point to primitive types too. In Java, reference cannot
reference a primitive type, unlees the wrapper class is used.
• In C/C++, pointer can point to another pointer, in Java, reference cannot reference
another reference.

Java is safer, C/C++ is more powerful.

Q. What modifiers should be used for main method? Why could I violate the rule,
and it still works?
A:
The official modifiers and signature for main method is

public static void main(String[] args){}

You should remember it, and use this for your SCJP test.

However, if you miss public or even use private instead, some JVM might let you launch
your Java application without complaining or error messages. Why?

Because some JVMs just make themselves more tolerant then they should be. This kind
of practice is very common in Microsoft world. I guess Sun learned something from
there. Take a look at stock price movements of both co. on 2001, you will probably
understand why.

• What will happen if I omit static modifier for main method? Should I do that?
Q. What will happen if I omit static modifier for main method? Should I do that?
A: The code will compile, but not functional as you wanted (if you want something
normal, of course).
The main() method is supposed to be the entrance of the entire application.

However, if you omit static, it is just another instance method, happen to be called main.
It will not work as you expected. It will make yourself and your coworker confused. also
make yourself confused. It will become maintenance hazard.

Something is legal does not mean it is recommanded!!!!!! Don't trouble troubles until
trouble troubles you!!!!

Q. How does Java compiler resolve the ambiguity to decide which methods to call?
A:
In the following example, four test() methods, if we pass ambiguous \b{null} to the test,
which one should (will) be called? The 3 on top has super/subclass/sub-subclass
relationship. The most specific one (down hierarchy) will be called. The 4th with String
as a parameter, but it is a sibling of Tester. Ambiguity compile time error results.
class Tester {
void test(Object s) { System.out.println ("Object version"); }
void test(Tester s) { System.out.println ("Tester version"); }
void test(SubTester s) { System.out.println ("SubTester version"); }

// Not compilable any more if you uncomment the line


// since String and Tester are siblings
// void test(String s) { System.out.println ("String version"); }

public static void main (String args[]) {


Tester c = new Tester ();
// Ambiguous, the most specific one which fit will be call
c.test (null); // SubTester version
c.test (new Object()); // Object version
}
}

class SubTester extends Tester{


}
"The informal intuition is that one method declaration is more specific than another
if any invocation handled by the first method could be passed on to the other one
without a compile-time type error." Quotation from JLS2

Q. Where can I put labels in Java?


A: See the example here. The comments and commented code tells you everything.
public class Test {
// lbla: //compilable Error: identifier expected
public static void main(String[] args) {
// lblb: //compilable Error: A declaration cannot be labeled
Object o = new Object();
int n = 1;

lblc:
if (o instanceof Object) {
while (true) {
n++;
if (n > 5)
break lblc;
System.out.println(n);
}
}

System.out.println("Finished n");

lblx:
for (int i = 3; i < 7; i++){
// skip number 5
if (i==5)
continue lblx;
System.out.println(i);
}

lbly: // legal before another lable


lblz:
{
System.out.println("Watch:");

break lbly;
// compilable Error: statement not reached
//System.out.println("This will never be printed out.");
}
}
}

Q. What is the return type of constructor, if any?


A: General answer is constructor has no return type.

Quote from Java 2 : The Complete Reference by Patrick Naughton, Herbert Schildt,
Herb Schildt Pg. 147:
Constructors look a little strange because they have no return type, not even void. This is
because the implicit return type of a class' constructor is the class type itself

It makes sense. Just think of this:


MyObj o = new MyObj();

Q. What are the differences between arguments and parameters?


A:
In method call point of view, they are the same. The two words used alternatively for
historical reasons. The same reason for so many alternatives for method, such as function,
procedure, sub, subroutine, ... If you use those words in different context, then that is a
different question, I need to find my English dictionary first...

Q. Is null the same as void in Java? Can I return null in a void return type method?
A: No! Another No!
void means return nothing. null in Java means it is a reference type, but refers nothing.
null and void are very different things. For further interest, read here.
Q. What is the difference of null in Java and NULL in C++?

Q. Can we put a continue in a switch-case statement?


A: Answer is a hesitated YES, since it can happen in a special case.
// Guess the print out, then run it.
// A good IQ test
public class A {
public static void main(String args[]) {
int x = 0;
while (x < 10) {
System.out.print(" " + x);
switch (x) {
case 5: x += 2;
continue;
case 2: break;
case 7: break;
default: x++;
};
x++;
}
}
}

Q. How to compile 2 Java files simultaneously? The two inter-dependent files are
sitting on 2 different hard drives.
A:
If you are a beginner of Java, please give yourself a break by not doing this. If you're
experienced Java programmer, I don't think your boss will ask you to do this.

Keep It Simple and Stupid (KISS). Please!

But if you insist, figure it out! I guess it can be done, and here is something which
might help:
Q. How to create my own package, how to call my class in another package?

Q. What are the rules to name a Java file without public class defined in it?
A:
Everyone knows one Java file only can contain one public class, and the file must be
named as the name of the public class name. But how about Java file with no public
class?
No restrictions on name of Java file without public class defined. If you have a class with
a main, you'd better name the file with that class name for your own convenience.
However, this is not required. Test this out!
// D.java
class A {}
class B {}
class C {}
class E {
public static void main(String[] args) {
System.out.println("Strange thing in E.");
}
}
class F {
public static void main(String[] args) {
System.out.println("Strange thing in F.");
}
}
It is called D.java. You can run it in 2 ways:
java E //output: Strange thing in E.
java F //output: Strange thing in F.

If you think carefully, there are good reasons for this. Testing is one of them.

Q. Why cannot I use private access modifier in my interface definition?


A: See original discussion here.
Everything declared in interface are implicit or explicit public. If you don't put anything
there, they are public (not default). No access modifiers other than public allowed.

Q. Where can I find Java Grammar?


A:
The best answer is to read the JLS, THE JAVA LANGUAGE SPECIFICATION from
the source. Java grammar is officially defined there.
For your academic type, there is an interesting site, called Lykkenborg eZine. The author
tried to make Java grammar easier to navigate.

Primitive Types in Java and Type Casting

Q. What is void? Is void a Java type?


A: void means nothing. You mark a method void means the method returns nothing.
It is the same in Java/C++/C/C#. void is not a type in any of the languages.

Q. What is the difference of signed and unsigned integer?


A:
It is the interpretation of the first bit of the integer number been represented. If it is
signed, the first bit is 0 means it is a positive number, 1 means it is negative. If it is
unsigned, the first bit is just another bit, either to add (1) or not to add (0) 2n to the value
of the number. n is the bit location, 0 based counted from right to left.

Here is a binary representation of two bytes:


1111 1111 1111 0100
Signed : -12
unsigned: 65524

0000 0000 0000 1100


Signed : 12
unsigned: 12
If you don't understand how the negative number comes out, read the super article Two's
complement.

In java, only char is unsigned, others like byte, short, int, long are all signed. In other
languages like c/c++, all other types have a unsigned brother, char is always unsigned.

Q. Why char range is 0 to 216-1?


A:
0 to 216-1
0 to 65535
0 to 1111 1111 1111 1111
'\u0000' to '\uFFFF'

All of above are equivalent, since char is unsigned 2 byte integer.

For the first one, use your scientific calculator to do a little math. You can use the
following to understand it too.
1111 1111 1111 1111 + 1 = 1 0000 0000 0000 0000 = 216

Q. The size of long is 64bits and that of float is 32 bits. then how it is possible long to
float without type casting it?
eg.
long l=12345678;
float f = l; // ok to compiler
A: Interesting question!!!
The internal representation of integer types (byte, short, char, long) and floating point
number (float, double) are totally different. Converting from long to float is not a
narrowing conversion. Even it may lose some significant digits. See the following table
for details:

Primitive Data Types


default
# of value when
type range
bits it is a class
member

8, 1
Boolean bit true false false
used

char 16 '\u0000' '\uFFFF' '\u0000'

byte 8 -128 +127 0

short 16 -32,768 +32,767 0

int 32 -2,147,483,648 +2,147,483,647 0

long 64 -9,223,372,036,854,775,808 +9,223,372,036,854,775,807 0

float 32 -3.40292347E+38 +3.40292347E+38 0.0

- +
double 64 0.0
1.79769313486231570E+308 1.79769313486231570E+308

Q. Why char c = 3; compiles, but float f = 1.3; error out?


A:
char c = 3; byte b = 300; short s = 300; int i = 30000;

are assignments to integers(signed or unsigned) Compiler will do a range checking to see


if those value are in the range of the variable, if it is, ok; otherwise, error out!

float f = 1.3; float f = 1.3f; double d = 1.3;

are assignments to floating numbers. The difference between 1.3d and 1.3f is the
precision, not the range. 1.3 is default to double precision number, assigning it to a float
will lose precision. It will need a cast!

1.3 is different than 1.30 in physics/science, since different precision implication.

Distance d = 1.3 miles implies d is between 1.25 and 1.35 miles


Distance d = 1.30 miles implies d is between 1.295 and 1.305 miles, which is a lot more
precise measurement.

Of course, not everybody follows the convention.

Q. What are the variable initialization rules in Java?


A: Here we are:

• Member variables (both static and instance) are initialized implicitly by default:
1. Most primitives except boolean are default initialized to zero, not null!
2. boolean variables are default initialized to false, not zero, not null!
3. Only object references are default initialized to null!
4. Final varibles must be initialized explicitly in declaration or constructors
(instance final variable.)
• Local varibles are not initialized
1. They are not default intialized to anything, unless programmer initialize
them explicitly!
2. It is not compilable if you use them before assign them a value!

Q. Why byte to char, or float to long are narrow conversion defined by JLS?
A:
class My{
static long l;
static float f;
static char c;
static byte b;
public static void main(String[] ss) {
b=c; //not compilable
c=b; //not compilable either

l=f; //not compilable


f=l; //OK
}
}
Since char is 2 bytes unsigned integer, assign it to 1 byte signed integer will possible loss
precision. Opposite is true too, since the negative part of byte will be re-interpret to
positive and possible loss precision.

The float to long should be more obvious, since its decimal part will be lost.

Q. How many bits represent a boolean variable?


A:
Since boolean only has 2 states (true, false), one bit is absolutely enough for storing it.
However, in memory, we have no way to represent the address of each bit as a variable
address / reference, then we have to use one byte (8 bits) to make the variable
addressable. In other words, we only use 1 bit, and leave the other 7 bits unused.

To prove this theory, run the following program TestBoolSerialize.java. The output file
Bool.tmp and Byte.tmp will be the same size, but Short.tmp will be double the size. You
may need to run 1 section a time if you run out your memory.

Don't need to worry too much about internal representation is one beautiful thing of Java.
The programmer don't need to actively allocate/return memory like in c/c++. Don't you
remember the pain of using sizeof() in c/c++, because of the pointer arithmetic, etc?
There is no sizeof() in Java. My above program TestBoolSerialize.java actually does the
trick of sizeof() to reveal the secret of Java for you.

Q. What is type cast, can you give some simple example?


A: *** type cast ***
Cast the type of a variabe from one type to another, of course, it must be legal in
Java/C++ etc. Examples follow:
long l = 300L;
int i = (int)l; // cast a long to an int

class A {}
class B extends A {}

// will compile and run fine


A a = new B();
B b = (B)a; // cast A reference a to a B reference b
// runtime fine since a is actually a B

// will compile fine and ClassCastException will be thrown on runtime


A a = new A();
B b = (B)a; // cast A reference a to a B reference b
// runtime exception will be thrown since a is not really a
B

Q. How to cast between objects? How about interfaces?


A:

1. Upper cast from subclass to supercalss, no need to cast, since the ISA
relationship. OakTree is a Tree.
2. Down cast from superclass to subclass, an explicit cast is needed to avoid compile
time error. If you cast Tree to OakTree, it would possibly be right, but not
necessarily, since this particular Tree actually might be an AppleTree. In that
case, a ClassCastException will be thrown out at the run time
3. If you cast between siblings or even irrelevant classes, a compile time error
results, since compiler has the type information of them. for example, if you cast a
OakTree to an AppleTree, or even a Furniture, compile will error out.
4. However, there is a catch, if you cast to an interface, even they are irrelevant, and
compiler might let you go without an error.

See some interesting example and runnable code at TestCast.java

Q. Why this code compiles OK, but throw ClassCastException at runtime?


Base b=new Base();
Sub s=new Sub(); //Sub extends Base
s=(Sub)b;
A:
"Oversea Chinese is a Chinese", but not vise versa.
"Chinese is not necessary an oversea Chinese, but possible."

When you cast super to sub, compiler assume that you know what you were doing, since
it is possible. However, runtime will find out b actually is not a Sub.

Since Cat is an Animal, but Animal is not necessary a Cat, but it is possible a Cat.

That is why downcast is allowed on compile time, since compiler assumes you know
what you are doing. However, Runtime will find out this Animal is actually not a Cat.

ClassCastException! Big time.

Q. What are the differences between char and byte? Why text file can be read back
as byte streams?
A:

1. Everything in computer are represented by 0's and 1's, every eight 0's and 1's can
form a byte, that is why everything can be read in as byte streams.
2. byte is the smallest memory unit addressable.
3. How to interpret those bytes is the job of operation system, software, etc.
4. For Java primitive types, char is 16 bits unsigned integer, byte is 8 bits signed
integer, short is 16 bits signed integer.
5. The difference between char and short is the interpretation of the first bit.

Q. A case study, why 3 is printed out?


class Test {
public static void main(String[] args) {
Test t = new Test();
t.test(1.0, 2L, 3);
}
void test(double a, double b, short c) {
System.out.println("1");
}
void test(float a, byte b, byte c) {
System.out.println("2");
}
void test(double a, double b, double c) {
System.out.println("3");
}
void test(int a, long b, int c) {
System.out.println("4");
}
void test(long a, long b, long c) {
System.out.println("5");
}
void test(float a, long b, int c) {
System.out.println("6");
}
}

// output: 3
// think why?
A:
Remember the following will help:

• 3 (integer type) is always default to int in Java.


• 1.0 (floating point number) is is always default to double in Java.

Explanation correct or wrong:

1. Wrong! Since 3 is int, int to short needs explicit cast.


2. Wrong! Since all three parameters are wrong.
3. Correct! Since numeric promotions are performed on 2nd/3rd parameters.
4. Wrong! Since 1.0 is double, double to int needs explicit cast.
5. Wrong! Since double to long needs explicit cast.
6. Wrong! Since double to float needs explicit cast.

Java Objects

Q. Why hashCode must be the same for two objects equal to each other?
A:
This is a complicated question. Let us discuss it slowly.
• You must read the javadoc here first. Otherwise, we have no common ground. It
is excellent reading too!
• HashTable or HashMap are fundamental data structure in computer science. The
lookup speed is close to O(1), since we use hashCode to put (store) and look-up
(retrieve) elements. See more detailed explanation on HashTable here!
• Equal objects must have the same hashCode! It is a must, not a choice. Otherwise,
HashTable or HashMap will not work correctly!
• Different/unequal objects have different hashCodes or not, which has everything
to do with the efficiency of HashTable/HashMap etc. It is a trade-off between
time and space. Less collision will make look-up faster (saving time), but will use
more memory (wasting space).
• The hashCode generation/look-up algorithm usually considers the sparcity of the
hashTable to make the decision. However, since memory is so cheap now, people
no longer pay too much attention to the algorithm any more, UNTIL you have an
OutOfMemoryError, of course.
• Since Java made all of these behind the scene, it becomes more obscure to
developers. Good or Bad??? I think the answer is BOTH! The good side is
making coding easier, the bad side is some programmers don't understand them
any more. In real programming life, you might need to code them yourself for
efficiency or your application special needs.

Q. How many objects is created in String case?


A: Generally to say, please don't use String in Java to discuss creating a new object or
not. It just waste your time since Java using String Pool.
Here are two cases, read the comments, please!
String s1 = "Hello world!"; // If "Hello world!" is in String pool,
// no Object is created, otherwise yes, and
put it in the String Pool.
String s2 = new String("Hello world!"); // A new String object is
definitely created.

Q. How to use clone()method, why my code throws CloneNotSupportedException?


A: Make your class implements Cloneable interface, and override the Object.clone()
method.
If you don't override the Object.clone() method, the code will be compilable, but throws
CloneNotSupportedException. Why, see the following code copied from JDK
Object.java.
protected native Object clone() throws CloneNotSupportedException;

Q. What does clone() method do?


A:
The key concept you need to understand is the default implementation of clone() is a
shallow clone(). The primitive type is cloned, for example, the hashCode() (type long) of
the original and the clone will have the same value. If you change the clone's primitive
type field value, the original will stay the same as before.

But the reference type just clones the same object's reference. Therefore when you make
a change in the data member object, the original and the clone will be both changed.

I learned this the hard way. Then I had to write my deepClone() method to do my job.

Q. Can we cast an Object to cloneable?


A: Yes or No
It will compile, since compiler does not check interface casting. However, it will throw
java.lang.ClassCastException at runtime. Try the following example. See more type cast
example here TestCast.java
class T {
public static void main(String[] args) {
Object o = new Object();

// compile ok, throw java.lang.ClassCastException at runtime


Cloneable c = (Cloneable)o;

// not even compilable


// Object o2 = c.clone();
}
}

Java Packages

Q. How to start to define my own packages? Any suggestions?


A:
Suggestions:

• Don't put your own stuff under jdk. Create a directory such as c:/myworkarea or
c:/liuxia
• Create a stem directory, such as com/myco or org/myorg under your
c:/myworkarea
• No Java files should be put in your stem directory, only packages
• All your code will start with a package statement, and put them under the
corresponding directories. Examples: package com.myco.somepkg;
package com.myco.somepkg.somesubpkg;

That will be a good start.


If I define a class in com.myco package as com/myco/MyClass.java, How do I
compile and run it?
In your c:/myworkarea directory:
javac com/myco/pkg1/MyClass.java
java com.myco.pkg1.MyClass
However, this is just to get you started. The better practice is using ant. Start to learn Ant
now

Q. How to create my own package, how to call my class in another package?


A:
Here is a runnable example with detailed explanation for you to play and practice.
Package Usage

Q. What should I do when we have class name conflict?


A: Use fully qualified name.
Bad naming causes problem, you need naming your class name carefully. Don't call them
the same name as Java API classes. Another thing is make your class name meaningful.

However, sometimes, it happens. There is a Date class defined in java.util package, but
also java.sql package. When it does happen, use fully qualified name instead. Problem
solved, always!!!!
Examples for fully qualified names:

java.util.Date
java.sql.Date

Q. What are the rules and convention about package name? Why I got an error
when I used WEB-INF as my package name?
A:
package name in Java is an identifier, therefore it has to qualify as an identifier first. Read
JLS for rules of Java identifiers JLS 3.8 Identifiers To my limited knowledge of computer
programming languages, I do not know any programming language which allows dash '-'
as part of an identifier. Not in any of the followings: Pascal, c, c++, Fortran, c#, Ada, VB,
Lisp, Java, ML, perl, ... It might be allowed in COBOL, but I'm not sure, since COBOL is
a very loose language. I do not know COBOL. Any COBOL expert here? Help, please!
The first problem for WEB-INF as a package name is dash '-', of course. The second
problem is WEB-INF in tomcat or Java web component develop environment has special
meaning, you cannot use it for anything else.In all of above, we are not talking about
convention, but the rules. Read Java coding convention here: Code Conventions for the
JavaTM Programming Language What are the differences? If you violate the convention
only, your code should still compilable/runnable/workable, but not very good. Another
thing you need to remember is that conventions are very subjective. A good convention
in IBM shop might be considered bad in Microsoft or EDS.
Java Constructors

Q. What does keyword this mean?


A: keyword this is use in Java/C++/C# to refer to the object itself, just like "I" in human
languages.

Q. How to use super and this Java keywords?


A:
super();
this();
With or without parameters, only one of these is allowed as the first line in your
constructor, nowhere else! However,
super.method1();
this.field4;
do not have the above restrictions in your code.

Q. How does the Java default constructor be provided? Is it the same as C++?
A:
If a class defined by the code does not have any constructor, compiler will automatically
provide one no-parameter-constructor (default-constructor) for the class in the byte code.
The access modifier (public/private/etc.) of the default constructor is the same as the class
itself. Attention to former C++ programmers: It is very important to previous C++
programmers to know the differences between C++ and Java. C++ compiler will provide
a no-parameter-constructor (defult-constructor) as long as you did not define one. Java
only provide a no-parameter-constructor when your class does not have any
construcor.Can you let me see it? Oh, yes, in where your class file is, type
javap -private YourClassName
Your C++ programmer will be real happy to see the output very similar to a
YourClassName.h Of course, j2sdk/bin or jre/bin directory must on your path.

Q. Can constructor be inherited?


A: No, absolutely not!
Here is a good example. MyButton extends JButton, but did not add similar constructors,
then you cannot call the constructor with String or ImageIcon. Please read the comments
inside the code.
import javax.swing.*;
import java.awt.*;

class MyButton extends JButton {


int x, y;
}

public class MyFrame extends JFrame {


ImageIcon icon = new ImageIcon("btn.gif");

//Only default constructor works


MyButton bn = new MyButton();
Container cpane;

//JButton constructors are not inherited


//MyButton bn = new MyButton("Btn Text"); // not work!
//MyButton bn = new MyButton(icon); // not work either

MyFrame() {
cpane = getContentPane();
cpane.setLayout(new GridLayout(2, 1));
bn.setIcon (icon); //OK
bn.setText ("Btn Text"); // OK
bn.x=5;
bn.y=10;
JTextArea txtarea = new JTextArea("bn.x= "+ bn.x + "\nbn.y=" +
bn.y);
cpane.add(bn);
cpane.add(txtarea);
pack();
setVisible(true);
}

public static void main(String args[]) {


MyFrame myfrm = new MyFrame();
myfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Q. Does Java initialize static variable first when we instantiate an Object?


A: Wrong question! Please do NOT mix static field initialization with Object
construction or instantiation!

• static field initialization happens at class loading time, it only happens once, and
once only. It might be changed long before your object instantiation time!
• When you compile and run a toy program, it might look correct. However, the
real world programming is NOT a toy!
• Someone might think "what the article said should be correct at least once, at least
correct at the first Object is instantiated." No, that is not necessary true either,
since you might call on static method of that class long before the first Object is
instantiated. The static value has been initialized and changed long before the first
Object is instantiated.

Q. Why does my following code not compilable?


class Base{
public int i = 0;
public Base(String text){
i = 1;
}
}
public class Sub extends Base{
public Sub(String text){
i = 2;
}
public static void main(String args[]){
Sub sub = new Sub("Hello");
System.out.println(sub.i);
}
}
// Compile error:
// Sub.java:8: cannot resolve symbol
// symbol : constructor Base ()
A:
Because you did not explicitly call super(String) in Sub contructor, a default super() is
added. However, the super class of Sub does not have a Base() constructor. ERROR!
How to solve the problem? Two choices:

1. Explicitly call super(String) in Sub constructor


2. Add a no-param-constructor for Base()

See the following detailed commented code, uncomment either one will work
class Base{
public int i = 0;
/* ----------------- choice #2
public Base() {
// do whatever
}
*/
public Base(String text){
i = 1;
}
}
public class Sub extends Base{
public Sub(String text){

// super(text); //-- choice #1

// problems here!!!
// since if you don't, then a default
// super(); //is generated by compiler

i = 2;
}
public static void main(String args[]){
Sub sub = new Sub("Hello");
System.out.println(sub.i);
}
}

Q. Why does my following code not compilable? How to fix it?


class A {
int i;
A(int k) {
i = k;
}
}
class B extends A {
public static void main(String args[]) {
A a = new A(10);
System.out.println(a.i);
}
}
/* Compile Error:
C:\>javac B.java
B.java:7: cannot resolve symbol
symbol : constructor A ()
location: class A
class B extends A {
^
1 error
*/
A: You need to understand how compiler works
The problem of your code:

1. You did not define a constructor for B, compiler will define a default no-
parameter constructor for you.
2. The compiler defined no-parameter constructor will auto-call superclass A no-
parameter constructor.
3. The superclass A no-parameter constructor does not exist!!!!
4. Compile ERROR, big time!!!!!!!!!!!!!!!!!!!

How to fix it, I give you three choices follows:

solution #1, define a no-parameter constructor for A

class A {
int i;
A() {
}
A(int k) {
i = k;
}
}
class B extends A {
public static void main(String args[]) {
A a = new A(10);
System.out.println(a.i);
}
}

solution #2, define a with-parameter constructor for B, which in turn calls with-
parameter constructor for A

class A {
int i;
A(int k) {
i = k;
}
}
class B extends A {
B(int k) {
super(k);
}
public static void main(String args[]) {
A a = new A(10);
System.out.println(a.i);
}
}

solution #3, define a no-parameter constructor for B, which in turn calls with-
parameter constructor for A

class A {
int i;
A(int k) {
i = k;
}
}
class B extends A {
B() {
super(56);
}
public static void main(String args[]) {
A a = new A(10);
System.out.println(a.i);
}
}

Q. Can I specify void as the return type of constructor? It compiles.


A: No, you cannot!
However, why it compiles? Yes, it you code it tricky enough, it will compile without any
error message!Surprised? Proved? Ha, ha, Roseanne is wrong?! Wait a minute, hmmm...
it is not a constructor any more! It is just a method happen to have the same name as the
class name Try the following code! Please! It will be a very very interesting experience
and lots of fun too!
public class A {

// this is a constructor of class A


public A(int i) {
System.out.println("We are in contructor: A(int i)");
System.out.println("The i value is " + i);
}

// this is a method A
void A() {
System.out.println("We are in method: void A()");
}

public static void main(String[] args) {

// They are fine here!


A a1 = new A(3);
a1.A();

// Compile time error


// cannot resolve symbol constructor A()
// A a2 = new A();
}
}

// output
// We are in contructor: A(int i)
// The i value is 3
// We are in method: void A()

Access Modifiers, etc.

Q. What is abstract method?


A: Method marked as abstract means the method has no body!
The subclass need to implement all abstract method to become usable non-abstract class.
public abstract void saySomething(); // must have no body here!

Q. Is it a must for a abstract class to have a abstract method?


A: No!
All methods defined in interfaces are abstract.
All classes which have abstract method(s) must be declared abstract, but not vice versa.

Q. Can one object access a private variable of another object of the same class?
A:
Yes! One object can access a private variable of another object of the same class. The
private field can be accessed from static method of the class through an instance of the
same class too.Here is an example:
public class Test1 {
private int i;
Test1(int ii) {
i = ii;
System.out.println("Self: " + i);
// to avoid infinite recursion
if (i != 3) {
Test1 other = new Test1(3);
other.i++;
System.out.println("Other: " + other.i);
}
}
public static void main(String[] args) {
Test1 t = new Test1(5);

// The private field can be accessed from


// static method of the same class
// through an instance of the same class
System.out.println(t.i);
}
}

Q. Several questions about static:


a) Can a static variable be declared within a method?
b) Can a static method contain an inner class?
c) Can a static method contain an static inner class?
A:
a) No, not in Java, but yes in C++
b) Yes
c) No
The simplest way to have your doubts clarified is to write a short program, then compile
it to see the result. CODE, Code, code, ... please! An example here:
class Test {
void method() {
//static int i = 3; // not compilable
}
static void smethod() {
//static int i = 3; // not compilable
class local {
}
/* not compilable
static class slocal {
}
*/
}
}

Q. Why the following code not compilable? Do we need to initial final variable
explicitly?
public class Test{
static int sn;
int n;
final static int fsn;
final int fn;
}
A:
The above code is not compilable since final variable fsn and fn are not initialized.Yes,
final variable (variables), static or instance, must be initialized explicitly. It can be done
by an initializer, static or instance respectively. final instance variables can also be
initialized by every constructor.Three choices to make the code right:
public class Test{
static int sn;
int n;
final static int fsn = 3;
final int fn = 6;
}

public class Test{


static int sn;
int n;
final static int fsn;
final int fn;

static {fsn=6;}
{fn =8;}
}

public class Test{


static int sn;
int n;
final static int fsn;
final int fn;

static {fsn=6;}

Test(){
fn =8;
}
Test(int pn){
fn =pn;
}
}

Q. Can we declare an object as final? I think I still can change the value of a final
object.
A:
final variables cannot be changed.
final methods cannot be overridden.
final classes cannot be inherited. However, there is something easily to be confused.
There is no final Object in Java. You cannot even declare an Object in Java, only Object
references. We only can have final object reference, which cannot be changed. It is like
that the address of your house cannot be changed if it is declared as final. However, you
can remodel your house, add a room, etc. Your house is not final, but the reference to
your house is final. That is a little confusing. By the way, use finals as much as possible,
but do not overuse them of course. It is because compiler knows they are not going to
change, the byte code generated for them will be much more efficient.

Q. Can we use transient and static to modify the same variable? Does it make any
difference in Object serialization?
A:
Yes, we can use transient and static to modify the same variable. It Does not make any
difference in Object serialization. Since both transient and static variables are not
serializable.See your exausting example at TestSerialization.java

Q. What happens if we don't declare a constructor as public? Is it a useful strategy


somewhere?
A:
Following discussion is based on the assumption of that your class is declared as public
and at least has some public members, and the other package imports your class or using
full-qualified names to use your class.

1. You cannot construct an instance of the class by using this constructor in another
package.
2. If you have other constructors declared public, you still can construct an instance
of the class by using other public constructors in another package.
3. If all your constructors are not public, then the class cannot be constructed in
packages other than the package it was defined.
4. If the other package gets a reference to it, its public members still can be used.
Singleton Design Pattern is a good example for it. We even use private construtor
intentionally.

Q. In a non-static inner class, static final variables are allowed, but not static
variables! why?
A:
When a variable is static final, actually, it is not a variable; it is a constant. Compiler will
treat it differently.

Q. Can final and transient be used together? Why?


A: Yes, they can.
final variables cannot be changed.
final methods cannot be overridden.
final classes cannot be inherited. transient variables cannot be serialized. They are
independent of each other. A variable can be final or a constant (an oxymoron, right? ),
and transient or not serializable. I actually figured out a good reason not to serialize final
variables.Serializing objects are mostly for transferring data. The both side of transferring
will know the Class object, know the constants in most of the cases, with the exception of
initialized finals in constructors by using the parameter value. Not Serializing the final
will certainly save transferring time. Using final and transient together will certainly have
some advantages in distributed computing. And, please remember, putting final and
transient together is an option, not a requirement.
Q. Why null variable can access static member variables or methods?
A:
When you call a static data member or method, all it matters is right type. See example
here
// ST.java
class ST {
static int n = 3;
static int getInt() {
return n + 35;
}

public static void main(String[] args) {


ST st = null; // st has the type of ST

System.out.println(st.n); // 3
System.out.println(st.getInt());// 38

// the above lines are equivalent to the followings


System.out.println(ST.n); // 3
System.out.println(ST.getInt());// 38
}
}

Q. Should we hide private method defined in the superclass by defining the same
name and signature method in the subclass?
A: No.
If super class defined a private method, it hides itself; nobody else can see it or use it.
That is exactly what private means. It does not need a subclass to define a same name
and signature method to be hided!!!If the subclass use the same name and signature to
define another method, it does not hide anything, it is just itself and totally irrelevant with
the super class same name method. In addition, it should be only considered a bad-coding
style, even it is legal.Please read everything about hiding here!
a section in JLS2

Q. Why I got IllegalAccessException when I try to use reflection or dynamic proxy


to access some package level methods from another package?
A: Why not?
Do you think what you get is the reasonable behavior of Java? OR Do you assume Proxy
or reflection should break the rule of Java, and open a backdoor to a class, and let it do
something, which it is not supposed to do?

Q. What is modifier for the default constructor implicitly generated by Java


compiler?
A:
The default constructor implicitly generated by Java compiler should have the same
accessibility as the class. i.e. public class will have a public default constructor, package
"friendly" class will have package "friendly" constructor, unless you explicitly define it
otherwise.See Package usage example for details.

String and StringBuffer

Q. What is the difference between String s = "hello"; and String s = new


String("hello"); ?
A:
Read Sun's explanation here:
http://java.sun.com/docs/books/tutorial/java/data/stringsAndJavac.html

Q. Why String and StringBuffer works differently, discrimination?


// Test.java
public class Test {
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = new String("hello");
StringBuffer sb1 = new StringBuffer("hello");
StringBuffer sb2 = new StringBuffer("hello");
System.out.println("String: s1.equals(s2) = " + s1.equals(s2));
System.out.println("StringBuffer: sb1.equals(sb2) = " +
sb1.equals(sb2));
}
}

// output
/*
String: s1.equals(s2) = true
StringBuffer: sb1.equals(sb2) = false
*/
A:
Since String class overrides the equals() method of Object class, and StringBuffer does
not.
Read here: equals method and check the JDK doc for String and StringBuffer too.

Q. How does Java String concatenation, or the overloaded + between different


types, work?
A:
Go to your JDK1.2.2/JDK1.3 directory, find src.jar, unjar it. Then you can see all source
code of JDK.Goto src\java\lang, to find StringBuffer.java and String.java. Search for
append in the beginning comments of StringBuffer.java, then follow the lead, you will
find out all the secrets you are interested in. "If you give me a fish, You feed me for the
day.
If you teach me how to fish, you feed me for life."
Q. Does "+" use in String concatenation affect efficiency?
A: Traditional answer: Yes. Actually answer: No

• Traditional answer: Yes. Why?


"a" + "b" + "c" is bad expierence because in memory the JVM will create "a", "b",
"ab","c", "abc" which here, "ab" is a waste...Therefore you should always use
StringBuffer.
• Actually answer: No. Why?

From SLS at http://java.sun.com/docs/books/jls/

15.18.1.2 Optimization of String Concatenation

An implementation may choose to perform conversion and concatenation in one


step to avoid creating and then discarding an intermediate String object. To
increase the performance of repeated string concatenation, a Java compiler may
use the StringBuffer class or a similar technique to reduce the number of
intermediate String objects that are created by evaluation of an expression.

For primitive types, an implementation may also optimize away the creation of a
wrapper object by converting directly from a primitive type to a string.

Q. Why are outputs of these two statements so different?


System.out.println(6 + 4 + " = sum"); // 10 = sum
System.out.println("sum = " + 6 + 4); // sum = 64
A:

• Java evaluates the expression inside println(expr) first, then convert it to a String.
• When Java evaluates the expression, it follows the left-to-right rule.
• "+" operator is overloaded in a very intuitive way just as in most other languages.
• In 6 + 4 + " = sum": from left to right, evaluates 6 + 4 first, two integer adds,
10 resulted. Then 10 + " = sum", int plus a String, String concatenation
assumed, converts 10 to a string, then ...
• In "sum = " + 6 + 4: from left to right, "sum = " + 6, String plus an int,
String concatenation assumed, converts 6 to a String, concatenates them together,
become "sum = 6". Then repeats the same process with "sum = 6" + 4. You
know the answer.
• String concatenation process actually is finished by a class StringBuffer. If you
want to know the details, read the source code of jdk: StringBuffer.java. It is
highly recommended for you to do that.
Methods Overloading and Overriding

Q. What is the basic difference between the concept of method overloading and
overriding?
A: They are totally irrelevant except the name similarities in two senses.
sense #1: English words overriding and overloading both have "over" inside
sense #2:overloading methods will have the "same name" but different signature.
overriding methods will have the "same name" and same signature.

Except these above, there is nothing in common between them. Please read some more
from the following QAs.

Q. Can overloaded methods in derived class hide the same name methods (with
different signature) in base class?
A:
When methods are defined with the same name, but different signature, they are just
name overloading, nothing can hide anything else. It is irrelevant it is in a derived class or
not.

1. American people drive on the right side.


2. You are right on this topic.
3. He will be right back.

English word right is overloaded here, we understand the difference by the context.
Compiler understands the method overloading by the signature, which serves the same
purpose as context, but more reliable, since compiler is not as intelligent as you are. If
derived class (subclass) defines a non-private method with the same name and same
signature as the non-private method defined in base class, then it is method overriding,
polymorphism comes into play. Late binding/Runtime binding will happen.Never mix
these two words overriding and overloading, please.

Q. Can overloaded methods be override too? Static binding or dynamic binding?


A: Yes, of course!
In compiler point of view, overloaded methods are totally different methods. Because
compiler identifies methods by their name and signature, you know overloaded methods
must have different signatures.

Derived classes still can override the overloaded methods. Polymorphism can still
happen. Compiler will not binding the method calls since it is overloaded, because it
might be overridden now or in the future. It is compiler's responsibility to check the caller
class has the method being called. It is the runtime's responsibility to call the right
method along the hierarchy from bottom-up according to the real Object type identified.

Q. What are the differences between overloading and overriding? Are they both
concepts of polymorphism?
A: No, overloading is NOT a concept of polymorphism.
Let me try a short one about overloading. The approach is like you take the test, cross out
something obviously not correct, before you decide what is correct. 3 + 5
3.0 + 5.0
The plus (+) operator is overloaded long before even OO concepts came into play in
computer sciences. It is in Fortran (the first high level computer language) for sure.

1. American drives on the right. British drives on the left.


2. Maha Anna is right on this topic.
3. I'll be right back.
4. These are right angle triangles.
5. You have the right to disagree with me.
6. He is a right extremist.
7. Actually, you can even overload the English word right to mean a dog in certain
communication circle. Just thinking a scenario, you name your dog as Right, then
in your family, when you or your kids talk about Right, the most of the time, it is
referring to the dog. And it is a valid overloading; no body will put you in jail
or even criticize you for your use of English word right this way...
8. ...

The English word right is overloaded here. All natural languages are overloaded long
before computer even invented. Polymorphism is a very specific OO concept, which has
nothing to do with overloading. You really need to read a good OO book to understand it.
It is too large a job for me to write about it here. There is so much misunderstanding out
there on this topic, a lot of them are in published books. Like Marcus said: "Don't
believe everything you read." If you don't believe what you read here by Roseanne, I'm
OK.
P.S. The word Polymorphism itself in natural languages can be overloaded too like the
Right example in English. You can overload the word polymorphism with whatever
meaning you want it to mean. However, I still agree with most computer scientists'
narrow and precise definition of polymorphism. If you don't agree with me, no more
arguments are needed; we all can rest in peace...

Q. When ambiguity exists between method calls, how does compiler resolve it? Why
String version of the method is called instead of the Object version in the following
example?
// Overloading.java
public class Overloading {

public void method(Object o) {


System.out.println("Object Version");
}

// String is an Object, but a specific Object


public void method(String s) {
System.out.println("String Version");
}

public static void main(String args[]) {


Overloading test = new Overloading();

// null is ambiguous to both methods


// The more specific one is called
test.method(null); // String Version
}
}
A:
The answer is in the comments of above code; just remember that when ambiguity exists
between method calls, compiler resolves it by choosing the more specific ones. If it does
not work, it will error out.

Why String is more specific than Object?

This is a Basic OO concept about generalization/specialization, read here for more


specific information. Here is a brief:

OakTree is a specific Tree.


Cat is a specific Animal.
String is a specific Object.
Subclass ISA specific Baseclass.

Q. An interesting example of ambiguity when program calls overloaded methods


A: There is no exact match between eat() methods. However, the JVM know which one
to call.
There are 3 eat() methods, which create the ambiguity for illustrating the concepts. Read
the comments in the code.
public class EatDesertTest {
void eat(Dessert d, Cake c){
System.out.println(" eat(Dessert d, Cake c)");
}
void eat(Pie d, Dessert c){
System.out.println("eat(Pie d, Dessert c)");
}
void eat(ApplePie a, Cake c){
System.out.println(" eat(ApplePie a, Cake c)");
}
public static void main(String [] args){
ApplePie anApplePie = new ApplePie();
ChocolateCake aChocolateCake = new ChocolateCake();
EatDesertTest edt = new EatDesertTest();
// three eat() are all correct.
// but eat(ApplePie a, Cake c) is the most specific one
edt.eat(anApplePie, aChocolateCake); // eat(ApplePie a, Cake c)
}
}
class Dessert {
}
class Pie extends Dessert {
}
class ApplePie extends Pie {
}
class Cake extends Dessert {
}
class ChocolateCake extends Cake {
}

Q. Can overloaded methods have the same signature but different return type?
A: No, absolutely not!
In any programming languages, Methods overloading only applies to methods with
different signatures. If same signature, there is only one method, two return types is
impossible for one method. Try 5-10 line of code in Java or C++, you get your
answer.Read here from JLS 8.4.7 Overloading

If two methods of a class (whether both declared in the same class, or both inherited by a
class, or one declared and one inherited) have the same name but different signatures,
then the method name is said to be overloaded. This fact causes no difficulty and never of
itself results in a compile-time error. There is no required relationship between the return
types or between the throws clauses of two methods with the same name but different
signatures.

However, If we have two overloaded methods (which means they have the same name,
but different signatures), they can have same/different return types, and/or throw
same/different exceptions.

Q. Can static method be overridden?


A: No!
The concept of overriding is binding at runtime, or polymorphism. Static is just on the
opposite side of the equation, binding at the compile time, polymorphism does not apply
to static method.

Methods a Subclass Cannot Override A subclass cannot override methods that are
declared final in the superclass (by definition, final methods cannot be overridden). If you
attempt to override a final method, the compiler displays an error message similar to the
following and refuses to compile the program:"
... "Also, a subclass cannot override methods that are declared static in the
superclass. In other words, a subclass cannot override a class method. A subclass can
hide a static method in the superclass by declaring a static method in the subclass with
the same signature as the static method in the superclass. " Quotation from Overriding
Methods of The Java Tutorial

See more interesting discussion and sample code here: Can subclass override methods
that are declared static in the superclass?

Q. Can constructor be overridden?


A: No!
No, constructor cannot be overridden. Constructor must have the same name of the class
itself, can never be its ancestor's name. For constructor calling orders, read here: What is
the calling order of constructors along the hierarchy, from child up, or from ancestor
down?

Q. Can you explain the result of the following example? Oh, my!
class Base {
public boolean foo(Base b) {
return true;
}
}
class Sub extends Base {
public boolean foo(Sub s) {
return false;
}
}

public class Test {


public static void main(String argv[]) {
Base bb = new Base();
Base bs = new Sub();
Sub ss = new Sub();

System.out.println(bb.foo(bb)); //true

System.out.println(bs.foo(bs)); //true ???


System.out.println(bs.foo(ss)); //true ???
System.out.println(bs.foo(bb)); //true ???
System.out.println(ss.foo(bs)); //true ???
System.out.println(ss.foo(bb)); //true ???

System.out.println(ss.foo(ss)); //false
}
}
A: The foo methods are overloaded in the Sub. In Base, there is only one foo method, and
it is not overridden by the Sub!
Overloading is fundamentally different then overriding. There is no polymorphism or
dynamic binding here!!! All decisions are made at compile time!!! See detailed
explanation in the same code below, documented!
class Base {
// There is only one foo method in Base!!!
public boolean foo(Base b) {
return true;
}
}
class Sub extends Base {
// differnt signature, method overloading
// there are 2 foo methods in the Sub
public boolean foo(Sub s) {
return false;
}
}

public class Test {


public static void main(String argv[]) {
// bb is a Base ref to the compiler, Base obj at runtime
Base bb = new Base();
// bs is a Base ref to the compiler, Sub obj at runtime
Base bs = new Sub();
// ss is a Sub ref to the compiler, Sub obj at runtime
Sub ss = new Sub();

// All these 4 lines are Base ref


// call Base.foo(Base) method, and only one foo available
// bs is a Base ref, and ss ISA Base ref too
// Everything is fine!!!
System.out.println(bb.foo(bb)); //true
System.out.println(bs.foo(bs)); //true
System.out.println(bs.foo(ss)); //true
System.out.println(bs.foo(bb)); //true

// bb, bs are both Base refs to Compiler


// ss is a Sub ref
// call Sub.foo(Base) which is inherited from Base
System.out.println(ss.foo(bs)); //true
System.out.println(ss.foo(bb)); //true

// no doubt about this one, am I right?


System.out.println(ss.foo(ss)); //false
}
}

• Are Java and C++ using the same rules on method overriding/overloading?

Q. Are Java and C++ using the same rules on method overriding/overloading?
A: Yes, they are basically the same.
Here are two equivalent class A/B in Java and C++. Compare carefully!

A.java

public class A {
public int mtdA(int x) {
return x + 3;
}
public int mtdB(int x, int y) {
return x + y;
}
}

class B extends A {
/*
$ javac A.java
A.java:23: mtdA(int) in B cannot override mtdA(int) in A;
attempting to use incompatible return type

found : double
required: int
public double mtdA(int x) {
^
1 error

public double mtdA(int x) {


return x + 0.2;
}
*/

// Compiled OK
public double mtdB(int x) {
return x + 0.2;
}
}
A.cpp
class A {
virtual int mtdA(int x) {
return x + 3;
};
virtual int mtdB(int x, int y) {
return x + y;
};
};

class B : public A {
// $ g++ A.cpp
// A.cpp:15: error: conflicting return type specified for `virtual
double B::mtdA(int)'
// A.cpp:2: error: overriding `virtual int A::mtdA(int)'
/*
virtual double mtdA(int x) {
return x + 0.2;
};
*/

// OK
virtual double mtdB(int x) {
return x + 0.2;
};
};
Basic OO concepts

Q. What is abstraction, what is encapsulation? What is the difference?


A:
pine tree, apple tree, oak tree....
Abstraction: Tree
They are all trees.
Another way to express the same concepts is generalization and
specialization.Capacitor, resister, wire, box, CRT, ...
Encapsulation: television
You don't care what are inside the black box, and how they interact with each other, as
long as the television works.
Another way to express the same concepts is information hiding.

Q. Why we need to construct a Vector first, then we can call addElement method?
A: See original discussion here.
Since addElement(Object) is an instance method of class Vector. If we don't construct a
Vector instance first, we cannot call instance method. You may askWhy we define
addElement(Object) as instance method?
The answer should be obvious. You might use different Vectors in different parts of your
application. Each Vector might add very different Objects. Define addElement as static
(class) method does not make any sense.Give you a simple analog, you build a home,
which is an instance of Home class, then add a TV to your living room. The addTV()
method must be called after you construct your home, in other words, an instance
method. Do you want you TV to be a class static variable and used by all home owners.
No, you don't, and it is also impossible in reality too.

Q. When an instance of subclass is created, is an instance of base class created also?


How many objects are created during the process?
A:
A short lessen on Inheritance:
~~~~~~~~~~~~~~~~~~~~~
Truth: FordCar ISA or "is a" Car.Think:
Which one is generalization/specialization? (Answer: Car is generalization)
Which one should be the base/sub class? (Answer: Car should be the base class)Fact: A
FordCar was just made.Questions:
true/false? A Car was just made. (Answer: true)
How many objects (Cars) were created during this process? (Answer: one)
~~~~~~~~~~~~~~~~~~~~~There is only one object, but it contains all of the variables
for the entire hierarchy. The reason being that the execution of a constructor causes calls
to the constructors all the way back up the hierarchy to java.lang.Object - as each
constructor executes, it gets the memory and sets the variables as required for that
class.Where I can learn more about this topic?Reading some good Java / C++ / OO
books, pay attention to the inheritance (or generalization/specialization) part. This is a
big and extremely important topic. Yes, it is more important than learning Java. "Nothing
can replace the technique of reading a good book from front to back." Here is an
excellent free book:
Bruce Eckel's Thinking in Java, 2nd Edition

Q. Another interesting example to illustrate the concepts. It might be controversial


too.
A:
An Asian boy was born.

A boy was born.


An Asian was born.
A human was born.
A creature was born.

All above statements are true. How many creatures were born during the process?

Only one!
This very Asian boy inherited all its base class features as a boy, an Asian, as a human,
and as a creature.

If you happen to be a Darwinist, do not believe creation, if you are doing research on the
development of human embryo, you might even understand how those constructors were
called during the process.

Q. When we should use static methods, when we should use instance methods?
Which one is better?
A:
This should depend on what problem you need to solve. If the method is a long
complicated scientific calculation, static method is the right way to do it. It makes the
method available and easy to be used everywhere. That is exactly what Java Math class
does. Go there, and see it.If the method is an individual behavior, such as
putOnMakeUp() , it is very cultural/personal dependent. Putting it as static method
would be almost meaningless. Of course, you can make a static putOnMakeUp() work
fine if you are willing to pass 15 parameters to it, or pass a large struct including all
cultural/personal information needed. Ah, we drive our time machine and go back to that
magnificent procedural/structural paradigm era...
Q. What does multi-inheritance mean? Are the following examples multi-
inheritance?
//1.
class A{
//...
}
class B extends A{
//...
}
class C extends A{
//...
}
//2.
class A{
//...
}
class B extends A{
//...
}
class C extends B{
//...
}
A: No! They both are not multi inheritances.
Conceptual explanation:

1. Apple is a Fruit.
Banana is a Fruit.
2. Apple is a Fruit.
FujiApple is an Apple.

Why don't you just compile the code to see what is allowed???

The following code is not allowed!!!!

class A{
//...
}
class B{
//...
}
// Sub extends both A and B is not allowed
// Java does not support multi-inheritance!!!!
// However, ........ you fill this out!
class Sub extends A, B{
//...
}
Multi-inheritance is perfect legal in C++
class A{
//...
}
class B{
//...
}
class Sub : public A, public B{
//...
}

Q. When should I use inheritance, when aggregation?


A: They are Two different relationships!
He is a human, human has a heart!
ISA: inheritance
HASA: aggregation

Q. What is the differences between association and aggregation?


A: Examples to illustrate the differences, they can both called as composition.

• Aggregation implies encapsulation (hidding) of the parts of the composition.


Object aggregation is a natural way of representing a whole-part relationship, (for
example, molecules are aggregates of atoms, Human has a Heart, Car has an
Engine.)
• An Association is a composition of independently constructed and externally
visible parts. When we associate classes or objects, each one keeps a reference to
the ones it is associated with. For example: : MyWebsite has a link to
OtherWebsite. MyWebsite doesn't have OtherWebsite, but only has a link.
• The difference of the two is more clear in C++, since you can have an Object of
another class(Aggregation), or you can have a pointer to another class
(Association). It is not so clear in Java, since both are references.

Q. Why upcast is wrong concept?


A: upcast is a wrong word with wrong concepts, even many people or even some
published books are using this word.
AppleTree is a Tree, AppleTree don't need upcast to be a Tree.
AppleTree atree = new AppleTree();
System.out.println((atree instanceof Tree)); // true!
Tree anotherTree = new AppleTree(); // correect, since AppleTree is a
Tree, no upcast at all!

Q. Why compiler forces me to downcast? Does compiler just ignore my instanceof


logic?
// Employee is superclass of Manager
if (employee instanceof Manager){
Manager m = (Manager)employee; //If no cast, compile errors
}
A: Yes, compiler does not read your logic to make decision. Compiler makes decision
according grammar rules.
Manager is an Employee, however, Employee is not necessary a manager. Employee can
be a cafeteria janitor or something else. If you don't cast it to Manager, compile error
results. Compiler does not analyze your logic at all to make decision. Compiler makes
decision according grammar rules. Unless you explicitly cast, which means you know
what you are doing, compiler will tell you "NO!".

However, do a instanceof check before casting is a very smart decision, since otherwise,
you will encounter possible runtime exception - ClassCastException!!!!

To prove compiler does not analyze your logic, see and run the following code. A
Manager is just instantiated one line ago, explicit cast is still required. Compiler does not
make decision according to your logic. No matter it is one-line-ago or 10000-line-ago. e
is the type of Employee, assign it to Manager, explicit cast is required.

class Employee {}
class Manager extends Employee {}
public class T1 {
public static void main(String[] args) {
Employee e = new Manager();
Manager m = (Manager)e; // if not cast, error!
}
}

Inheritance, polymorphism, static/dynamic binding, etc.

Basics

Q. Does subclass inherited all fields and methods from the superclass? Do they all
accessible?
A: Yes, then No.
All superclass information has to be inherited to make subclass functional. However, not
all superclass information are accessible or visible by subclass. Encapsulation or
information hiding is a basic concept of OO. If superclass set some fields or methods
private, they will be invisible by subclasses. Default fields or methods are only accessible
by subclasses in the same package.

Why do all superclass information must be inherited ? That is because subclass might be
able to put its hands on the private fields through public or protected getters and setters.
Also, some private method might be called inside of public/protected methods.

Q. Which one of the methods defined in interface or class with the same name will be
called?
A:
There is no method in interface can be called. Only the actual implementation of that
method in class, which implements the interface mentioned, can be called.

Q. Can subclass override methods that are declared static in the superclass?
A: No!
"

Methods a Subclass Cannot Override A subclass cannot override methods that are
declared final in the superclass (by definition, final methods cannot be overridden). If you
attempt to override a final method, the compiler displays an error message similar to the
following and refuses to compile the program:"
... "Also, a subclass cannot override methods that are declared static in the
superclass. In other words, a subclass cannot override a class method. A subclass can
hide a static method in the superclass by declaring a static method in the subclass with
the same signature as the static method in the superclass. " Quotation from Overriding
Methods of The Java Tutorial

When you should use this kind of "hide" technique?


Don't use it unless your boss gives you the assignment!!! Then you have no choice.
Something legal does not mean it is recommended.
Copied from Sun's Code Conventions for the JavaTM Programming Language
Quote:

Avoid local declarations that hide declarations at higher levels. For example, do not
declare the same variable name in an inner block:

An interesting example here:


class Base {
static void doThis() {
System.out.println("Base static doThis()");
}

void doThat() {
System.out.println("Base instance doThat()");
}
}

class Sub extends Base {


// This is static method defined in the Sub class
// which does not override the Base doThis()
// only hide it.
// proved in the Test.main()
static void doThis() {
System.out.println("Sub static doThis()");
}

// This is instance method defined in the Sub class


// which does override the Base doThat()
void doThat() {
System.out.println("Sub instance doThat()");
}
}

public class Test {


public static void main(String[] args) {
// base is an instance of Sub
Base base = new Sub();
// legal cast both at compile and run time
Sub sub = (Sub)base;

base.doThis(); //Base static doThis()


base.doThat(); //Sub instance doThat()

sub.doThis(); //Sub static doThis()


sub.doThat(); //Sub instance doThat()

//Think why, try to understand the following concepts


//static binding : bind at compile time
//Dynamic binding : bind at run time
}
}

Q. If subclass overrides the methods in super class, can subclass call the super class
method?
A:
Yes, you can. However, that is the subclass it self's choice. Outsider does not have this
choice. You can see it clearly from the following example.
class Sup
{
void m1()
{
System.out.println("m1 in super");
}
}

class Sub extends Sup{


void m1()
{
super.m1();
System.out.println("m1 in sub");
}
}

public class T{
public static void main(String arg[])
{
new Sub().m1();
}
}

Q. Are non-static fields (variables) dynamically bound?


A: No, fields or variables are always bound at compiling time.

• Fields or variables is static bound (decided) at compile time.


• Non static method is dynamically bound (decided) at runtime.

In theory of programming languages, there is a deep explanation for this. Variables must
be bound at compile time. However, I think remembering the fact is much more
important than knowing why...

Q. What is hide(a variable or a static method) means in computer languages (such


as Java)? Should we do that?
A:
Hide basic is a scope issue, when we have the same name in a smaller/more local scope,
the smaller scope one will hide the upper ones.

Here is a real life example: If you call your daughter Oprah Winfrey, then in your home,
or in your daughter's kindergarten, people talk about Oprah Winfrey will refer to your
daughter. The popular talk show host Oprah Winfrey will be hidden, unless you refer her
as talk show host Oprah Winfrey. This example tells you three things:

1. Hiding is a scope issue.


2. Hiding cannot be complete/absolute.
3. Hiding is not good practice, since it causes confusion.My suggestion is don't call
your daughter Oprah Winfrey, or don't practice hiding in your Java or C# or ...
programming.

The followings are two Java programs to illustrate the hiding concepts.
// hiding a instanse variable
class A {
int i = 3;
void method1() {
// this i will hide the member i
// bad coding practice
int i =5;
System.out.println(i); //5

// however, it can still be accessed by using this.i


System.out.println(this.i); //3
}
}

// hiding a static method


class A {
static void method1() {
System.out.println("in class A's static method1");
}
}

class B extends A {
// this will hide the static method1 in class A
static void method1() {
System.out.println("in class B's static method1");
}

public static void main(String[] args) {


// since we are in class B's scope
// call method1 directory will refer to B's method1,
// A's method1 is hidden
method1(); //in class B's static method1

// However, we still can call A's method1 even in B's territory


A.method1(); //in class A's static method1
}
}

Q. Can you give an example to illustrate the difference of static/dynamic binding


and static method cannot be overriden?
A: static method is bound (determined) at compile time.
You can easily to find the difference by use the following example. Pay attention to the
comments and the run results.
class A {
static void method1() {
System.out.println("A.method1()");
}
void method2() {
System.out.println("A.method2()");
}
}
public class B extends A{
// will not override A.method1()
static void method1() {
System.out.println("B.method1()");
}
// will override the A. method2()
void method2() {
System.out.println("B.method2()");
}
public static void main(String[] args) {
A a = new B();
// static bound with A.method1(), since a is A reference
a.method1(); // A.method1()
// dynamically bound to B.method2(), since a actually refers Object
B
a.method2(); // B.method2()
}
}

Q. Why the call to xy.amethod() calls amethod() in X instead of amethod() in Y in


the following code?
class X {
public static void jout(String s) {
System.out.println(s);
}
static void amethod() {
jout("In X, amethod()");
}
}
class Y extends X {
static void amethod() {
jout("In Y, amethod()");
}
}
class Z extends Y {
static void amethod() {
jout("In Z. amethod()");
}
}
public class Test
public static void main (String[] args) {
X xy = new Y();
X xz = new Z();
Y yz = new Z();

xy.amethod();
xz.amethod();
yz.amethod();
}
}
A:
All three amethod()s here are static methods. static method is Class method, which has
nothing to do with your object instantiation, dynamic binding, or polymorphism,
whatsoever. In other words, the 3 line of codexy.amethod();
xz.amethod();
yz.amethod();can be replaced by the following 3 lines without causing any
changes:X.amethod();
X.amethod();
Y.amethod();Since compiler interprets them exactly like this. xy and xz are reference
type of X. yz is reference type of Y.Just remember "static is not dynamic" probably will
help some.

Q. When base class calls a method, how could the run time knows to called the
overridden method in the derived class? The object is not even constructed yet.
A:
Why? From the language theory, it is called deferred binding or dynamic binding or
binding at run time. Compiler leaves the decision to run time. To make the decision at run
time, you don't need the object built first. The only thing you need to know is the type of
the actual object. In Java, the Class (not class) objects are loaded to the memory when it
is first used. The run time knows it before any instance is constructed. In C++, the class
methods virtual table is there for the same purpose. As you probably know, in C++,
method are default to static binding, only virtual methods are dynamically bound. In Java,
methods are default to dynamic binding, unless they are declared as static, private, or
final.
Q. Does private method defined in base class participate polymorphism, if the
derived class has a same name method?
A: No, private method defined in any class will never participate polymorphism.
If you want to confuse yourself, your boss, and your co-worker (and you might get fired
for that too), and define same name private methods along the hierarchy, the compiler
will treat them individually, as no relationship at all. If you call private method in your
class, the method will be bound at compile time (not runtime).See the following example:
// Base.java
public class Base {
public static void main(String[] args) {
Sub sub = new Sub();
System.out.println(sub.g()); // 20, not -100
}

private int f() {


return 20;
}

protected int g() {


// statc bound with Base.f()
// compiler does not know any derived class has f() or not
// and does not care either
return f();
}
}

class Sub extends Base {


// f() here has nothing to do with Base.f()!!!
// In real world programming, never do this!!!
public int f() {
return -100;
}
}

Q. An example to illustrate private method is static bound at compiling time.n


A: It is bad code in practice, but a good example to illustrate the concepts.

• b is a Base reference, but points to a Sub at runtime.


• method1 is private in Base, therefore it is static bound at compiling time.
• Even Sub has a same name method, it is NOT an override of the Base same name
method.
• To avoid confusion, please don't write code this way.

class Base {
private void method1() {
System.out.println("Base.method1()");
}

public void method3() {


System.out.println("Base.method3()");
method1();
}
}
public class Sub extends Base {
public void method1() {
System.out.println("Sub.method1()");
}

public static void main(String args[]) {


Base b = new Sub();
b.method3();
}
}

// run output
// Base.method3()
// Base.method1()

Q. What kind of Java methods does not participate polymorphism?


A:
Polymorphism for Java method is always there except the following three situations:

1. The method is declared as final


2. The method is declared as private
3. The method is declared as static In those three cases, static binding will be
performed by the compiler. Compiler does not have the knowledge, nor care
about the method was, is, or will be overridden by none, one, or many
subclass(es). The decision is made by the runtime, which is called dynamic
binding.

See next question, which discuss the same topic in a different angle.

Q. What methods in Java is static bound? Please compare with c++ too.
A: static, private, final methods are static bound.
Those 3 methods does not participate polymorphism. In other words, they are not allowed
to be overridden. In c++, virtual function can be overridden, others not.
virtual in C++ --> nothing in Java
nothing in C++ --> final in Java

Q. Do we need an object reference to call a static method?


A: No, not quite. See the following example.
MyClass t = null;
// the following two are equivalent
t.aStaticMethod();//OK
MyClass .aStaticMethod();//perfect
It is the class type; it doesn't need a "reference variable ". You can use a object reference
to call a static method, of course, provided it has the right type. However, you don't have
to. The above example clearly said that. t is not referring to anything but null, but has a
MyClass type. If you know the old procedural programming, static method is equivalent
to that, except in Java, we have a class Class. In Java, we can write magnificent old
procedural program without any OO concepts by using all static methods. (No object
reference at all). Wow, what a deal?

Harder Ones

Q. What is the calling order of constructors along the hierarchy, from child up, or
from ancestor down?
A:
The order is from child up. However, the super() is always implicitly or explicitly called
as the first statement before any code in the child being executed. This might cause some
confusion here. If you put a print statement in each of the constructor, the ancestor one
will be output first. The following code will illustrate how it works.This is called LIFO,
which one is called the first, will be finished the last. The child is called first, but it call
its parent as the first statement, and the immediate parent will call its parent as the first
statement too, and so on. Therefore the far ancestor, which is the Object will finish its
constructor the first, then its immediate child, and so on. That is why the print statements
will finish from the ancestor down. The calling stack is working this way. Last In, First
Out (LIFO)
public class Child extends Parent {
public Child() {
// super() is implicitly called here
System.out.println("Child");
}
public static void main(String[] args) {
new Child();
}
}
class Parent extends GrantParent{
public Parent() {
// super is explicitly called here
super("Mother's parent");
System.out.println("Parent");
}
}
class GrantParent{
public GrantParent(String sWhosPrt) {
System.out.println("GrantParent: " + sWhosPrt);
}
}

// output
// GrantParent: Mother's parent
// Parent
// Child
Q. What is the static, instance initialization, constructor header, and code execution
order? Why the radius prints out as 0 instead of 1 in the following code?
//Ex from Bruce Eckel's Book "Thinking In Java"
abstract class Glyph {
abstract void draw();
Glyph() {
System.out.println("Glyph() before draw()");
draw();
System.out.println("Glyph() after draw()");
}
}
class RoundGlyph extends Glyph {
int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println(
"RoundGlyph.RoundGlyph(), radius = " + radius);
}
void draw() {
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}
//Output is:
//Glyph() before draw()
//RoundGlyph.draw(), radius = 0
//Glyph() after draw()
//RoundGlyph.RoundGlyph(), radius=5
A:
The execution order is:

1. static variable initialization and static block executes only once when the class is
loaded to the memory by JVM.
2. When constructor is called, the constructor header executes first before instance
variable initialization and instance block execution.
3. instance variable initialization and instance block execute.
4. Code in the constructor executes.

This is exactly what happened in your example (except no static stuff). The RoundGlyph
constructor header executes first, which implicitly called default constructor of Glyph
super(). The radius has not initialized yet; the value is 0. Then the radius is initialized to
1. Then the code in the RoundGlyph() constructor executes and changed radius value to
5. This kind of hair splitting trick, we'd better not know it, or don't tell your boss you
know it. I probably learned from Mughal and Rasmussen's book, which I gave away after
the test. Today, I wrote a little code to prove that I remembered it right. I usually do not
pay a lot of attention to what is going to be on the SCJP test like Marcus Green does,
however, it is quite safe to say, questions like this will NOT be on your test.Warning:
Don't try this at work!

Q. Constructor or not constructor? Please explain why the output of the following
code is null?
public class My {
String s;
public void My(){
s = "Constructor";
}
public void go() {
System.out.println(s);
}
public static void main(String args[]) {
My m = new My();
m.go();
}
}
//output : null
A:
public void My() is not a constructor. The default constructor is called. s is still null by
default.Constructor is not supposed to have a return type, even a void type. If it has, then
it is not a constructor, but a method, which happens to have the same name as the class
name. This is a tricky question just for testing your Java knowledge. Using class name as
your method name is not considered as good code practice at work!

Q. Base b = new SubBase(); How the compiler/Runtime to resolve the addresses of


methods calls, Fields?
// TestBinding.java
class Base {
String s = "string in Base";
void init(){
System.out.println("init() call in Base");

}
}
class SubBase extends Base{
String s = "string in SubBase";
void init(){
System.out.println("init() call in SubBase");

}
}

public class TestBinding {


public static void main(String[] args) {
Base b = new SubBase();

// static binding on instance fields


System.out.println(b.s); //string in Base
// dynamic binding on instance methods
b.init(); //init() call in SubBase
}
}
A:
The above example plus comments actually told everything you need to know.When a
field of an object is accessed using a reference, it is the type of the reference declared,
which determines, which variable will actually be accessed.
Static Binding -- Bind at compile time: The addressing of the field is determined at
compile time.

When a method is invoked on an object using a reference, it is the class of the current
object denoted by the reference, not the type of the reference that determines which
method implementation will be executed.
Dynamic Binding -- Bind at run time: The addressing of the method is determined at
run time.Notice to C++ programmer: In C++, only virtual methods (functions) are bound
at run time. In Java, methods are default to dynamic binding, unless they are declared as
static, private, or final.

Q. If I remove the init() from the Base in the above question, I got a compile error:
""method init() not found class Base". Why?

A: Incredible great question!!


It will make you understand dynamic binding or polymorphism much better. If you
remove init() from Base class, you actually take init() out of the polymorphism between
Base and SubBase class. Compiler only know b is refer to a Base class, which does not
have the method init(), compile time error!!! The Java compiler does not know, nor care
who, when, where, how some other class is going to extends the Base class, there are
some different named methods defined in them. And one of them happens to be called
init(). They are totally irrelevant to the Base class.Remember SubBase ISA Base.
Compiler does not care which child/grandchild/grand grandchild down the hierarchy b is
actually referring to, and which init() it should call. However, they all have an init()
(polymorphism). It is a runtime decision. Dynamic Binding.Dynamic binding, or
binding at runtime only for those methods defined in Base class, either inherited or
overridden by the subclass. The override can be already happened now or will happen in
the future, the compiler does not care.

Q. Here is another tricky code example for you to cracking on! Cover up the
explanation to see you can explain it or not.
class Base {
int x = 3;
public Base (){}
public void showx(){
System.out.println("In base, x = " + x);
}
}
class SubBase extends Base {
int x = 2;
public void showx() {
System.out.println("In SubBase, x = " + x);
}
}

public class BindingTest {

public static void main (String args[]){


Base b = new SubBase();
b.showx();
System.out.println("In Main, the (?) x = " + b.x);
}
}

// output
/*
In SubBase, x = 2
In Main, the (?) x = 3
*/
A: Danger: Do not try this at work!

1. In main(), b.x is bound at compile time, since b is declared as Base, x is 3.


2. In main(), b.showx() is bound at runtime, since b is actually a SubBase. the
SubBase.showx() will be called.
3. In SubBase, call of x in method showx() is bound at the compile time, in class
SubBase, x is 2. This is a typical tricky question, good for you cracking the
concepts, but never write it on your job. You would be fired for that, no kidding!!!

Abstract Classes / Interfaces

Q. Why do we need interface?


A: This is an OO concepts, we define a protocol, then we can use it by contract, we don't
care what is the implementation.
Here is a commonplace example to illustrate the concepts. We have the PCI board in our
computer, which define the interface, then all your SoundCard, GraphicsCard, etc. as
long as they implement the interface, they are OK to plugin. Some illustrative sample
code follows.

Q. What are the implicit access modifiers in interface?


A:

• All the variables defined in an interface must be static final, i.e. constants.
Happily the values need not be known at compile time. You can do some
computation at class load time to compute the values. The variables need not be
just simple ints and Strings. They can be any type.
• All methods in an interface are implicitly declared public and abstract. All
variables in an interface must be constants. They are implicitly declared public
static final.

Q. What are the differences between abstract classes and interfaces?


A:

• Interface is abstract, but not vice versa. There should be nothing implemented in
interface. Abstract class can be partially implemented.
• A class can only extend one class; abstract class is included.
• A class can implement multi interfaces.
• You need to learn some basic OO concepts of inheritance and polymorphism,
which apply not only to Java, but also to other OO languages, and even your real
life.

Q. Can abstract class have static method?


A: This example plus comment tells you everything.
abstract class A {
// OK
static void doSomething() {
}
// illegal combination of modifiers: abstract and static
// abstract static void doOtherthing();
}
interface B {
// modifier static not allowed here
// static void doSomething();
}

Q. Can we pass an interface as parammeter to a method? If yes, how does it work?


A: Yes, definitely.
It is not only correct, but also is recommended. Since the implementation class can
change, but the method will stay the same. There are tons of excellent examples in the
Java collection framework. It is also very useful to implement some design patterns such
as FactoryMethod Pattern. How to use it? When you make the method call, you must
pass a concrete implementation of the interface to it.
See the following example.
// TestFace.java
interface IFace{
void drawFace();
}
class RealFace implements IFace {
public void drawFace(){
System.out.println("I'm drawing a beautiful face");
}
}

public class TestFace {


// this code is aginst interface, and know nothing about
// underneath implementation
public static void callIFace(IFace face) {
face.drawFace();
}
public static void main(String[] args) {
// if this code changes to a FaceFactory, you will not see class
name RealFace here.
// the class name can be read from an outside property file
// then the code will become totally scalable in the future.
IFace face = new RealFace();
//pass interface to the method
callIFace(face);
}
}

Q. How to find out "What and Who" about an instantiation of an interface?


A:
Insert line like this. You will find out what is instantiated, and who did it.
Statement stmnt = connection.createStatement();
System.out.println(stmnt.getClass());
This is the print output you will see if you are using JDBC-ODBC Bridge:
class sun.jdbc.odbc.JdbcOdbcStatement
Try to do the same on enumeration or some other interfaces or abstract classes.

Q. Why abstract method Graphics.drawString() can work without implementation?


A:
Excellent question! The following is a statement copied from API doc"The Graphics
class is the abstract base class for all graphics contexts that allow an application to draw
onto components that are realized on various devices, as well as onto off-screen images."
Pay attention to the word devices, which means platform even hardware dependent. Then
you find your jre\lib\rt.jar file on your machine, use some un-archive utility to see the
names of some class files inside the jar file under sun\java2d\. Then you will know those
abstract Graphics stuff is actually implemented in a device-dependent way. The following
code will give you exact answer on WinNT:
import java.applet.*;
import java.awt.*;

class TestApplet extends Applet {


public void paint(Graphics g) {
g.drawString(g.getClass().toString(), 20, 30);
// output: class.ms.awt.GraphicsX
}
}
Q. What is the relationship between static and interface?
A:
static and interface:
1) Inner interfaces are implicitly static, no matter you put static modifier or not.
Attention: inner interfaces are very rarely used.
2) Outer interface are NOT static, just like outer class.
3) All members (attributes & methods) of interface are implicitly public.
4) All attributes defined in interface are implicitly static and final.
5) All methods defined in interface are NOT static.
6) All classes defined in an interface are implicitly static

Q. Can interface be extended?


A:
interface can be extended by another interface, but not by a class. For anonymous class, it
can be confusing. e.g.
interfacename ref = new interfacename() {
//implementation code here
}
The new anonymous class defined here is still implementing the interface named
interfacename, not extending the interface.

Q. Is it possible that we can run an abstract class with a main()?


A: Yes, as long as you do not instantiate the abstract class or call its abstract methods.
abstract class cannot be instantiated. However, if the main method only calls static
method of the class, you can run it just like you run any C program. See the following
example
public abstract class A {
static public int sum(int a, int b) {
return a + b;
}

abstract public void aMethod();

// abstract static combination not allowed


// abstract public static void aStaticMethod();

public static void main(String args[]) {


System.out.println("Sum of 3 and 5 is : " + sum(3, 5));

// The following code will not be compilable


// A a = new A();
// a.aMethod();
}
}

Inner, Local, Anonymous Classes

Q. Select the correct anonymous inner class declaration?


A) new Outer.new Inner
B) new Inner() { }
C) new Inner()
D) Outer.new Inner()
A:
All A) C) D) are not anonymous, all the classes have a name called Inner. They are not
declarations, but call of their constructors. Only B is anonymous class declaration, as well
as its constructor calling, since the anonymous class extends a class called Inner. The new
anonymous class is defined with an empty body. Remember, anonymous class is always
defined with its constructor calling. You cannot call its constructor anywhere else, since
it does not have a name.

However, in practice, you should not do that, it violates all the coding standards in
the world, even though it is legal and grammatically correct.

Q. What modifiers are legal to use to modify a nested member class?


A: The compiler says:
public class Test {
public static void main(String argv[]){
}
// all ok but one
public class MyInner1 {}
protected class MyInner2 {}
private class MyInner3 {}
class MyInner4 {}
final class MyInner5 {}
static class MyInner6 {}
abstract class MyInner7 {}

// not compilable
//transient class MyInner8 {}
}

Q. Is it possible that an anonymous class instance is referred outside of its scope of


definition?
A:
:
The answer is yes.
Anonymous class can be referred by the interface it implements or class it extends.
Remember the ISA relationship? Which is definitely a SCJP test stuff.
See sample code at InnerLocalAnonymous.java

Q. True or false? "An inner anonymous class is always assumed to extend Object."
A:
false. Not always. Anonymous class always extends the class (1) or implements the
interface (2) after the keyword new. In the second case, it extends Object.I assume that
extends or implements can only be implicit, in case of anonymous classes.See the
following example:
import java.awt.*;
import java.awt.event.*;

class Outer extends Frame {


public Outer(String s){
super(s);
addWindowListener(new WindowAdapter(){
// anonymous class extends WindowAdapter
public void windowClosing(WindowEvent e){
System.exit(0);
}
});

Button btn = new Button("Exit");


btn.addActionListener( new ActionListener(){
// anonymous class implements
ActionListener, and extends Object
public void actionPerformed(ActionEvent e){
System.exit(0);
}
} );

add(btn);
}

public static void main(String[] args) {


Outer f = new Outer("Test");
f.setSize(400, 300);
f.setVisible(true);
}
}

Q. Can we define a inner class in an interface? Is the following code compilable


and/or useful?
interface IFace {
public class X { //It is not member inner class
void method_Of_X() {
System.out.println("Without static modifier, it is still
static nested class.");
}
}

static class S { // static nested class.


void method_Of_S() {
System.out.println("static nested class.");
}
}
}
A:
Strange and surprising enough, the inner class defined in the interface is actually legal!!!
I compiled the code and it was perfect fine with JDK1.2.2 and JDK1.3. I also compiled
the code using jikes.exe, which means it is 100% JLS compliant. Attention: with or
without static modifier, X and S are both static nested classes.I can even think of a
situation in which it might be useful. A utility inner class will be used by all classes,
which implement the interface. It would be a way of cheating on no-multi-inheritance in
Java and actually made the interface fully implemented, provided the programmer is
tricky enough. Interesting stuff, isn't it? However, In general, I think that using too
many inner class or inner interfaces or even nested inner into another inner will
causing spaghetti code, and it is just at least as bad (if not worse) as the old goto. I
know someone who went to Sun's training class, and was told something similar. Many
companies have some coding standard to limit their use. I think that is absolutely
necessary!

Q. "To create an instance of an member class an instance of its enclosing class is


required." Is it true or false?
A: False!
Because member class include static and non-static (in other words, inner) enclosed
classes. Quotation from JLS: "Member class declarations (?.5) describe nested classes
that are members of the surrounding class. Member classes may be static, in which case
they have no access to the instance variables of the surrounding class; or they may be
inner classes (?.1.2)." Attention, here, or actually is an exclusive or (xor). e.g. "I will be
at school or at home." Not both, right? Unless, you're in quantum mechanics...

Q. What are the differences between static or non-static inner classes?


A:

1. There is no such thing as a static inner class. There are top-level classes and
nested classes, and nested classes are by definition divided into static and inner.
2. If it is static, it is not inner class, you can use it just as top-level class, but put a
qualifier as EncloseingClass.EnclosedClass.
3. If inner class is a member of enclosing class, it must be attached to an instance of
the Enclosing class, something like new EnclosingClass().new EnclosedClass().
4. Local and anonymous classes are also inner classes, they can be defined in
methods, initializers, which will be local to that enclosing scope.
5. Since the scope can be instance or static, Local and anonymous classes can be
defined in an instance or a static context.
6. Attention: JLS2 has got rid of "Nested top-level class" confusing terminology
now.
7. The correct name now is static member class, which in contrary to inner class
(non-static member class) in JLS2 now.
8. See more in Classes in JLS2
9. See an Inner/Nested/Local Class Example here. It is just for you to play with, it is
not comprehensive. Please pay attention to my "Don't try this at work" logo.
10. You can experiment unlimited combinations/permutations of
nested/inner/static/local/anonymous/member/etc/...
11. Warning: Try to use less nested (static/non-static) classes, since it easily results
error-prone, hard to maintain, spaghetti code
12. A summary table is suggested by Jim Yingst, I suppose you all know who he is. If
you don't, click here .

top-level class top-level


static member class nested static member
(non-static) member class nested inner member
local class nested inner
anonymous class nested inner

Q. An anonymous class cannot have any constructors. Is it true or false?


A: False, anonymous class has one and only one constructor.
You cannot explicitly define constructors for anonymous class, but compiler generates an
constructor for it with the same signature as its parent constructor called. If the parent has
more than one constructor, the anonymous will have one and only one constructor.Here is
an example. After you compile it, then do javap Test$1, you will see the compiler
generated one and only one constructor with the same signature as A constructor used,
even class A has two constructors.Does anonymous class has a name? Oh, yes! The
class name and the constructor would be, unsurprisingly, the same as the class file name.
Test$1 in our example.What is javap? See here!
// Test.java
class A {
int a;
// 2 constructors for A
A() {
a = 100;
}
A(int aa) {
a = aa;
}
public int m(int n) {
return a + n;
}
}
public class Test {
public static void main(String[] args) {
// Anonymous class extends A, override method m()
A oa = new A(12) {
public int m(int n) {
return a - n;
}
};
System.out.println(oa.m(5)); // 7
}
}

// javap Test$1 output


/*
C:\CODE>javap Test$1
Compiled from Test.java
final class Test$1 extends A {
Test$1(int);
public int m(int);
}
*/

Q. An anonymous class can only access static fields of the enclosing class. Is it true
or false?
A: false.
An anonymous class object can access static and instance fields when it has an associated
instance of the enclosing class (i.e. defined in a instance method). An anonymous class
can only access static fields when it is in a static context (i.e. defined in a static method).
" What it can't access is local variables (unless they are declared final). Attention:
parameters passed to the method are treated the same as local variables, since it is passed
by value and a local copy are really being used.See example at TestInnerEtc.java
Search for "local"

Q. Why does local class defined in a method only can access final local variables or
final parameters?
A:
Local class (anonymous or with a name) defined in a method can be returned by the
method, and it can live much longer than the method itself. See the question and answer
above Is it possible that an anonymous class instance is referred outside of its scope of
definition?However, the local variables are usually on the method calling-stack, and will
be out of scope when the method returns. And the parameters passed into the methods are
local copies of them (Read the topic pass-by-value). They will be out-of-scope too when
the calling stack returns.However, if it is final, the local class can treat them as constant,
and don't care what happens to the original variable any more.There is some complication
in the concepts of Java, since only primitive types are really automatic variables (on the
calling-stack). There exists some criticism on this practice of Java, since it is less
efficient. This is beyond the topics of SCJP, and enters the programming languages
theory domain.
Q. Can inner class extends outer class, or opposite? Why we should generally avoid
using this technique?
A: Yes, it is legal (inner class extends outer class, or opposite).
However, you would be better off by not using these features.An advice from Sun's
training class: Don't use inner class unless it is a very simple case.
Actually, abuse of inner class is much worse than the abuse of old goto. This is my
opinion, but not only mine. A lot of companies have very strict coding standard to
eliminate abuse of inner classes too. You are better off without using inner classes in
complicated projects. Inner class only gives you some convenience in simple cases,
such as Adapter etc. Just consider the following scenario:We make total 10 levels of
nested inner classes. 1) Let the 10th level inner class extends 5th level inner class, which
in turn extends outer class.
2) Let 7th level inner class extends 4th level inner class, which in turn extends 2nd level
of inner class.
3) The outer class extends 2nd level inner class (legal).
4) The 3rd level has 4 different inner classes, which extends different inner or outer class
individually.
5) One of them has a method3(), which has a local class extends outer class. 6) ... The
complexity can go on, and on, and on, and o...
Unpredictable results are guaranteed. Got the picture? Remember, compiler is written
by human beings, and uses certain grammar rules to do the job. The grammar rules only
can handle limited complexity. The set of combination and permutation of things are
unlimited. Grammar rules are not Newton's Law, or Einstein's Law of Relativity,
which are not made by human, but we discovered them.Assumption of programmer
will not do certain things (such as the above crazy stuff, even it is legal) will be made for
cost, efficiency, and simplicity purposes. If you really want to, you can drive compiler
crazy! In real life programming, if you find something does not work as you expected, try
alternatives, or report a possible bug (or a undocumented feature ). And it will never
be perfect, and it need not to be one either...
Write good enough software. One more point: Why I was/am so passionate to express
my view to against abuse of inner classes? It is because I'm a big believer of KISS.
"Keep It Simple and Straight forward" or "Keep It Simple and Stupid". I'm sure a
lot of visitors of this site are/will be leading software engineers/project
leaders/manages/etc in the software industry. If some of you will think twice when you
start to write code like some inner extends outer or opposite, it will be "music" to my
ears. See original discussion here. A similar but on a different forum here.

Q. A spaghetti and ravioli discussion, and inner class.


A:
Someone made this analogy:Procedural code can be like spaghetti - lots of long strands
twisted and knotted around each other and very hard to follow.OO code can be like
ravioli - a mess of small lumps with no obvious connection and no indication of what's
inside.However, if you overuse the inner classes of Java, you can make a mixed and
tangled spaghetti and ravioli. It would be really tastier than the old procedural code with
the famous goto.
Collection Classes

Q. What are the differences between Collection, Collections, and Java collections
framework?
A:
Confusing, Isn't it?Java Collections Framework: A generic name given to Java API of
collections classes/interfaces in java.util package.
Root interfaces of this API are Collection and Map. See Trail: Collections of Sun Tutorial
for details.Collection and Map: Root interfacesCollections and Arrays: Two classes
with all static utility methods. They are NOT interfaces.

Q. Can two different keys map to the same object elements? If yes, can you give an
example?
A:
The answer is YES. In the real world, that is easy. You may have a nickname and an
official name or even a fake name , they can be two/three keys in the map, and actually
are all mapped to the same physical person: YOU. See the following code example:
import java.util.*;
public class TestMap {
public static void main(String[] args) {
HashMap hm = new HashMap();
String sPerson = "The physical person";
hm.put("Official name", sPerson);
hm.put("Nick name", sPerson);
hm.put("Fake name", sPerson);
System.out.println(hm);
}
}

//output
//{Official name=The physical person, Fake name=The physical person,
Nick name=The physical person}

Q. Is TreeSet ordered? What is the difference between sorted and ordered?


A: Yes! TreeSet is an implementation of the SortedSet interface. It is sorted.
Sorted is ordered, and ordered is not necessary sorted. This is more philosophical
point of view than Java specific. As a former/current physicist, entropy decreases when
things are ordered or sorted. Sorted is a specialization of ordered. Ordered is a
generalization, which should include a specific order - sorted. They are not independent
of each other.From my freshman computer science course (Even when I was freshman, I
did not have any computer science courses. ), when you insert an item into an binary
search tree, it will be insert somewhere to make the tree still ordered by certain criteria.
The binary search tree is ordered by any sense to me.
Q. What does it mean that remove() method in Collection interface is optional? We don't
need to implement the method?
A:
optional: not compulsory
From http://m-w.com/cgi-bin/dictionary

Yes, you do need to implement the remove() method, otherwise, the implementation class
need to be abstract. When you need the functionality, then you implement it. Otherwise,
you actually can make it not usable (see example below), because it is optional.
Another question, I could do the same to any other methods, why this is announced
as optional? My guess is since this is documented as optional, then if it is not supported,
there will be no surprises to the user, which is an important principle in software
engineering. See the following code, the remove() method here is actually not supported
as the exception name indicated:

public void remove() {


throw new UnsupportedOperationException();
}

Q. When should I use Arrays and when should I use collection classes?
A:

• Using array whenever you can. It will not only save you time, but also save you
space/memory too. What a deal?
When you have fixed sized collection of objects, or the size is predictable, and
you are not going to insert, remove elements from the middle/front.
• Using ArrayList, Map, Set, etc. when you must.
• Try to avoid Using Vector, HashTable since they are synchronized and very slow:

Q. What are the differences between ArrayList and Vector? What should I use?
A:
HashMap and ArrayList have basically replaced their synchronized brother HashTable
and Vector. HashTable and Vector are about 3 times slower. If you think it is safer to use
HashTable and Vector, think twice, that synchronization only on the atomic operation
based, they usually give you a fake safe feeling, which might make your code less safe.

Use HashMap and ArrayList unless your boss commands you otherwise.

Or what you are doing is extremely security sensitive, the security should be obtained at
any price. In that case, I still don't think you will go to sleep soundly because you are
using Vector or HashTable.
Q. I can print my HashTable and obtain a string. Can I reverse the process?
A: All Java Object has a toString() method. They are not supposed to be reversable unless
you design your own.

Other Util Classes

Q. How to do arithmetic in Calendar class?


A:
Here is an example; we try to add 5 days to 02/28/2001:
import java.util.*;
import java.text.SimpleDateFormat;
public class G {
public static void main (String [] args) {
SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy");
Date date = null;
try {
date = df.parse("02/28/2001");
System.out.println(date);
}
catch (Exception e)
{
}

Calendar cal= Calendar.getInstance();


cal.setTime(date);
cal.add(Calendar.DATE, 5);
System.out.println(cal.getTime());
}
}
// output
// Wed Feb 28 00:00:00 CST 2001
// Mon Mar 05 00:00:00 CST 2001

Q. How to calcucate the date difference between 09-01-2002 23:59:59 and 09-02-
2002 00:00:01??
A:
Interesting question!!! The real time difference is 2 seconds. However, the date difference
is one. The answer will also be different when you are in a different time zone. The
different dates in London, UK does not mean different dates in Beijing, China. How do
we get the right answer?Here we are! A full functional tested answer can be found at here
. Enjoy!

Regular expressions
Q. How to use Pattern.split() method not to get empty strings?
My input string is "This is . a tough.sale. scenario." I want to get rid of spaces and periods
to get the tokens.
A:
Simple, here is the code:
import java.util.regex.Pattern;

public class P {
public static void main(String[] args) {
String input = "This is . a tough.sale. scenario.";
String pattern = "[\\s\\.]+";
Pattern patt = Pattern.compile(pattern);

String[] result = patt.split(input);


for (int i = 0; i < result.length; i++) {
System.out.println("\""+result[i]+"\"");
}
}
}

Q. How to use String.split() method, I want to use '|' as separator, it does not work.
A: Attention, Please!
In this method, parameter is a regular expression, not a delimiter list.
public String[] split(String regex);
Then you will know why you put String "|" as regex will definitely not work. Since '|' in
regex means 'or'. Then what will work? See this following code:
public class S {
public static void main(String[] args)
{
String str = "boo|and|asd||foo";

// If empty string is OK, then take the plus sign (+) off
String regex = "[\\|]+";

String[] toks = str.split(regex);


for(int i = 0; i < toks.length; i++) {
System.out.println(toks[i]);
}
}
}

Q. How to use regular expression to pickup all numbers from an arbitrary String?
A: Sample code
import java.util.regex.*;
public class Test {
public static void main(String[] args) {
String s = "whatever 45 -- ad8fadds9djjj 12342d2s";
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher(s);
StringBuffer sb=new StringBuffer();
while(m.find()) {
sb.append(m.group());
}
System.out.print(sb);
}
}

Multi Threading

Basics

Q. Why cannot we synchronized public object to lock the memory for avoiding
multi-thread access?
A:
synchronized has nothing to do with locking memory, but controlling access to a block of
code, which may access and change the memory/database/file contents, the integrity of
which might be compromized by multi-thread simultaneous access or changes. Here, I
intentionally missed how synchronized works, uses what kind of working mechanism.
Read other part of the FAQ for that, please. public/private/protected access modifiers
have no relationship with synchronized, even they share a word "access". They are for
encapsulation, in other words, information sharing or hiding. Like your family, you may
want certain information to be public, some to be known only by your relatives or close
friends, some to be kept only to your family members. Some might be kept to yourself
only, hoho, a secret. They are different concepts and serve different purposes.

Q. I found this statement about thread in some tutorial on Internet, Is it true?


The main thread must be the last thread to finish execution. When the main thread
stops, the program terminates.
A: Absolutely wrong!
The correct one:
JVM creates one user thread for running a program. This thread is called main thread.
The main method of the class is called from the main thread. It dies when the main
method ends. If other user threads have been spawned from the main thread, program
keeps running even if main thread dies. Basically a program runs until all the user threads
(non-daemon threads) are dead.This is actually most GUI (Swing) application works. The
main thread creates a thread for the GUI frame work; then it finishes and becomes dead.
The GUI will still running until the user closes it or something else kills it. Microsoft
GUI application basically works the same way.
A simple sample code (even not GUI) here!
class T extends Thread {
boolean runflag = true;
public T(String name){
super(name);
}
public void run() {
int i = 0;
while (runflag) {
System.out.println(getName() + ": " + i++);
try
{
sleep((int)(700*Math.random()));
}
catch (InterruptedException e) {
}
}
System.out.println(getName() + " is stopping.");
}

void setRunFlagFalse() {
runflag = false;
}

public static void main(String args[]) {


T t1=new T("t1");
T t2=new T("t2");
T t3=new T("t3");

t1.setDaemon(true);
t1.start();

t2.start();
t3.start();
try
{
// let three threads run
Thread.sleep(600);
}
catch (InterruptedException e) {
}

// t2 will stop
t2.setRunFlagFalse();

System.out.println("t3 will not stop after main stop");


System.out.println("t1 will stop after all user threads
stopped");
System.out.println("Use ^C to stop everything, when you had
enough");
System.out.println("main thread is stopping.");
}
}

Q. What is the basic concept of synchronized keyword, is it responsible to our data


integrity?
A:
The key concept of synchronized keyword is locking the code to prevent other thread to
access the critical code when one thread is processing it. You need acquire the
monitor/lock from an object to lock it, and one object only has one lock/monitor. That is
why when one thread acquired the lock/monitor, other threads have to wait. Why you
need to lock the code? Mostly you need to keep the integrity of your data, and which is
very application specific. The locking mechanism actually knows nothing about it. It is
NOT responsible for your data integrity at all. It is you, the application programmer, who
is responsible for it. For example, if you want to keep the integrity of your client's bank
account balance, you must synchronize all methods, which have access to and can change
the balance. If you leave a loophole there, you probably will be fired by your boss, not
Dr. Gosling or someone else who designed the locking mechanism. I just want to scare
you... However, when you are synchronizing the code, which has access to the client's
account balance, you probably still can change his/her email address or list of hobbies for
advertisement purposes. Of course, if you are really serious on that stuff too, you might
want to synchronize the code, which has access those data independently.Programmers
need to practice some examples to really understand it. Some times, I still get confused.
Concurrent programming is not an easy subject. It is not Java specific either. Race
condition, dead lock, critical section, semaphore, monitor, thread scheduling, thread
pooling, etc. etc...I'm still in the learning process... How about we learn together.

Q. Why we should call Thread.start() to start a Thread? I called the run() method,
no error or exception at all, why?
A:
When you call Thread start() method, JVM will create a new Thread, then call run()
method of the new Thread. The new Thread will run concurrently with the original
calling Thread.If you directly call the run() method, the Thread will act as a normal Java
object. No new Thread will be created. The code will run sequentially. Try the following
code to see the difference, and get a feeling of concurrency.
// MyRun.java
public class MyRun implements Runnable {
public static void main(String argv[]) {
MyRun r = new MyRun();
Thread t = new Thread(r);

// t is still running after Main finished


t.start();

// No new thread created, Main finishes after run() returns


// t.run();

try {
// See concurrency if you call t.start()
// See sequential if you call t.run()
for (int i = 0; i < 5; i++) {
Thread.sleep(10);
System.out.println("in Main: " + i);
}
}
catch (InterruptedException e) {
System.out.println(e);
}
System.out.println("Main thread finished...");
}
public void run(){
try {
for (int i = 0; i < 5; i++) {
Thread.sleep(20);
System.out.println("in Run: " + i);
}
}
catch (InterruptedException e) {
System.out.println(e);
}
System.out.println("Run method finished...");
}
}

Q. Thread t = null; t.yield(), is this legal? If it is, what is the effect of the statement?
A:
Yes, but it is bad coding style. It is equivalent to Thread.yield(), which will cause the
current thread to yield, and becomes ready state. The purpose of yield() is let other
Thread has a chance to execute.Since yield() is a static method of Thread class, the only
concern to compile is the type, that is why t.yield(); and Thread.yield(); are exact the
same. However, it is confusing human beings. It is bad, but legal practice. It is good for
you to really understand what is static method.

Q. In some mocking exam, after the definition of Thread t = new Thread(); then
both yield(); and t.yield(); are marked as alternative answers for causing the current
running thread to pause. Is it generally correct?
A:
No! It is generally incorrect. In some special situation, it will compile and work,
however, it should still be considered as bad coding practice. The special case is: when
yield(); is called inside a Thread class ( in a main, or other method ).You should use
Thread.yield() instead to accomplish the task. For more discussion, read the question
above.The following example shows you the general case, if you call yield(); it will not
compile.
// ThreadTest.java
import java.io.*;
class MyThread extends Thread {
public void run(){
for (int i=0; i<5; i++){
System.out.println(getName() + ": i = " + i);
}
}
}

public class ThreadTest {


public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
t.yield();
// Not compible this line
// since ThreadTest is not a Thread
//yield();
}
}

Q. What are the differences between notify() and notifyAll()? Do they release the
object lock?
A:
notify() does NOT relinquish the lock - it just lets the JVM know that it will be possible
to wake up a Thread that called wait() when the current Thread exits the synchronized
code. If you have more than one Thread wait() on an object, notify only wakes up one of
them - you can't predict which one. notifyAll() tells the JVM that all Threads waiting will
be eligible to run. The JVM will pick one - probably by looking at the priorities.

Q. When Thread.sleep() is called inside a synchronized method or block, does the


Thread release the object lock?
A:
No, Thread definitely does not release the lock before it goes to sleep, if it is in a
synchronized method or block. That is why we should use wait(), notify(), notifyAll()
defined in Object in synchronized method or block. Do not sleep() there unless you want
the program totally stop, please! Write some code, you will see it easyly. Or read JDK
Doc here: http://java.sun.com/j2se/1.3/docs/api/java/lang/Thread.html#sleep(long)Here is
a example, sleepInsteadOfWaitNotify() method causes t2 and t3 totally starved to death.
public class SleepTest implements Runnable{

public void run() {


while (true){
sleepInsteadOfWaitNotify();
}
}

synchronized void sleepInsteadOfWaitNotify() {


while (true) {
System.out.println(Thread.currentThread().getName() + "Go to
sleep");
try{
Thread.sleep(400);
}
catch (Exception e){
System.out.println(e);
}
System.out.println(Thread.currentThread().getName() + "wake up");
}

public static void main (String[] args){


SleepTest t = new SleepTest();

Thread t1 = new Thread(t);


Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");

t1.setDaemon(true);
t2.setDaemon(true);
t3.setDaemon(true);

t1.start();
t2.start();
t3.start();

try {
// let daemon threads run
Thread.sleep(10000);
}
catch (InterruptedException e) {
}
System.out.println("If user thread is dead, all daemon threads
die. ");
}
}

Q. In what situation, an IllegalThreadStateException will be thrown?


A:
1) If the thread was already started, you call start() again.
2) If this thread is active, you call setDaemon().
3) A deprecated method countStackFrames() also throws IllegalThreadStateException.

Q. What will be affected by assign a name to a thread using


setName("YourThreadName")?
A:

Quote from JDK documentation:


Every thread has a name for identification purposes. More than one thread may have the
same name. If a name is not specified when a thread is created, a new name is generated
for it.

Nothing changes by assigning your Thread a name. It only gives you the convenience of
debug, since it has a name you know.

Q. What is Thread.interrupt()supposed to do?


A:
interrupt is supposed to end the sleep or wait state of a Thread prematurely by causing an
InterruptedException.
Q. What is Daemon Threads?
A:
A daemon thread opposites to a user thread. The Java Virtual Machine exits when the
only threads running are all daemon threads. You threads are default to user thread unless
you explicitly use method setDaemon(boolean on) to set it as daemon thread. Note: You
cannot call setDaemon() after Thread has started, otherwise, an
IllegalThreadStateException (RuntimeException) will be thrown. Make sure you read the
JDK documentation of Thread and ThreadGroup. Javadoc is your best teacher to tell you
almost anything and everything about Java Threads.See sample code at ThreadTest.java

Q. Why Thread methods stop(), resume(), suspend() deprecated? How can we stop a
thread without call stop()?
A:
Why? Read here Why Are Thread.stop, Thread.suspend, Thread.resume and
Runtime.runFinalizersOnExit Deprecated?
How? See the following example:
public class T extends Thread {
boolean runflag = true;
public T(String name){
super(name);
}
public void run() {
int i = 0;
while (runflag) {
System.out.println(getName() + ": " + i++);
try
{
sleep((int)(400*Math.random()));
}
catch (InterruptedException e) {
}
}
System.out.println(getName() + " is stopping.");
}

public void setRunFlagFalse() {


runflag = false;
}

public static void main(String args[]) {


T t1=new T("t1");
T t2=new T("t2");
T t3=new T("t3");
t1.start();
t2.start();
t3.start();
try
{
// let three threads run
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
// stop them
t1.setRunFlagFalse();
t2.setRunFlagFalse();
t3.setRunFlagFalse();
}
}

Q. Can I use Thread.interrupt() to kill a thread? Is it a good idea?


A:
Yes, you can. As long as your handle the InterruptedException tricky enough in your
Thread.run() method, you can use interrupt() to kill a thread.However, it is absolutely a
bad idea to do this. Thread.interrupt() is a general purposed method to interrupt or stop
whatever a thread is doing now, such as sleep, wait, or living. If you used a general
purpose method to mean killing a thread, you create a side effect, and invite unaware
programmers to make mistake since they only read Sun's Thread javadoc.Stop is general;
stop life is special. General includes special, but general does not imply special. If it does,
it is a side effect. If stop sign on the street does also imply stop life, that would be really
bad!!!Never do this kind of stunt, please!

Please follow KISS rule in your code, Keep It Simple and Stupid, or Keep It Simple
and Straight forward. Do your boss and current/future coworkers a favor please!

There is one exception, if you're the boss, you can do and ask your employees do
whatever you want. If they do not follow your order, fire them!

If you want read more discussion about and opposite side of my opinion, read here!

Medium Ones

Q. What does the Thread.join() method do? Can you give an example?
A: The current running thread currT call another thread jobthread.join(), then wait until
the jobthread to die.
For example, the current running thread, which spawns the jobthread to do something (do
a long calculation, load several images, call somebody through satilite, etc. etc.). The
jobthread has been coded to do its job and then terminate or die, in other words, the
jobthread.run() method ends. The current thread will rely on jobthread's completion to
continue its own work. The effect of calling jobthread.join() statement is that currT waits
for jobthread to complete
public class JoinDemo {
public static void main(String[] args) {
Job job = new Job();
Thread jobthread = new Thread(job);

jobthread.start();
try {
// the current thread will wait until the job done
jobthread.join();
}
catch(Exception e){
}
System.out.println("Job done");
// do something else
}
}
class Job implements Runnable {
public void run(){
int i;
for (i=1; i<=200; i++ ){
if (i % 10 != 0) {
System.out.print(i + ", ");
}
else {
System.out.println(i);
}
}
}
}

Q. Is class wide lock and instance lock independent of each other?


A: Yes. Why?
Every Java Object has one lock, and only one lock. If you want enter synchronized code,
you have to acquire the lock first. When you enter the static synchronized code, you need
to acquire the lock on the Class object.
When you enter the synchronized instance code, you need to acquire the lock on the
instance object.
However, they are different objects with different locks, and independent of each
other.When you call a synchronized static method you get a lock on NONE OF the
instances of the class, except the Class object itself. Please pay attention to the
difference between class and Class. Run the following code, it will tell you the whole
story.
class MyObj {
String sName;

public MyObj(String name) {


sName = name;
}

// The Class Object of MyObj will be locked


// However, staticMethod() and instanceMethod() are independent of
each other
public static synchronized void staticMethod(String sThreadName) {
try {
System.out.println(sThreadName + ": staticMethod start lock");
Thread.sleep((long)(Math.random() * 2000 + 1));
System.out.println(sThreadName + ": staticMethod finish lock");
}
catch (InterruptedException e) {
}
}

// The instance Object MyObj of will be locked


// However, staticMethod() and instanceMethod() are independent of
each other
public synchronized void instanceMethod(String sThreadName){
try {
System.out.println(sThreadName + ": " + sName + ":
instanceMethod start lock");
wait((long)(Math.random() * 2000 + 1));
System.out.println(sThreadName + ": " + sName + ":
instanceMethod finish lock");
notifyAll();
}
catch (InterruptedException e) {
}
}
}

public class Test extends Thread{


String sTrdName;

// 2 objs for testing lock


static MyObj o1 = new MyObj("myobj1");
static MyObj o2 = new MyObj("myobj2");

public Test(String name){


super();
sTrdName = name;
}

public void run() {


while (true){
// Lock the Class object of MyObj
MyObj.staticMethod(sTrdName);

// Lock the instances object of MyObj


o1.instanceMethod(sTrdName);
o2.instanceMethod(sTrdName);
}
}

public static void main (String[] args){


Test t1 = new Test("t1");
Test t2 = new Test("t2");

t1.setDaemon(true);
t2.setDaemon(true);

t1.start();
t2.start();

try {
//let Daemon thread run
Thread.sleep(7000);
}
catch (InterruptedException e) {
}
System.out.println("If user thread is dead, all daemon threads
die. ");
}
}

// Output of the program clearly tell you the story


/*
t1: staticMethod start lock
t1: staticMethod finish lock
t2: staticMethod start lock
t1: myobj1: instanceMethod start lock
t1: myobj1: instanceMethod finish lock
t1: myobj2: instanceMethod start lock
t2: staticMethod finish lock
t2: myobj1: instanceMethod start lock
t2: myobj1: instanceMethod finish lock
t2: myobj2: instanceMethod start lock
t1: myobj2: instanceMethod finish lock
t2: myobj2: instanceMethod finish lock
t2: staticMethod start lock
t2: staticMethod finish lock
t2: myobj1: instanceMethod start lock
t1: staticMethod start lock
t1: staticMethod finish lock
t1: myobj1: instanceMethod start lock
t2: myobj1: instanceMethod finish lock
t2: myobj2: instanceMethod start lock
t1: myobj1: instanceMethod finish lock
t1: myobj2: instanceMethod start lock
t2: myobj2: instanceMethod finish lock
t2: staticMethod start lock
t1: myobj2: instanceMethod finish lock
If user thread is dead, all daemon threads die.
*/

Q. How to call wait(), notify(), notifyAll() in synchronized static methods?


A:
Direct calling those methods will not compile since those are instance methods inherited
from Object. When you call wait(), you are actually calling this.wait(), this does
not exist in static methods.

How can we solve the problem? There are two ways to do it.

1. Call wait(), notify(), notifyAll() methods of your Class object, by using


MyClass.class.wait(). synchronized static methods locks the Class, you
release lock of the same object.
2. Instantiate a static Object dummy in your class, you can use synchronized block,
which locks dummy, in your static method. Then you can call dummy.wait(),
dummy.notify(), ... in those blocks.
This is better when you have more than one set of static methods, which needs
locked independently, you can use more than one dummy objects for that
purposes.

If your problem is something like that a Queue problem where add and remove
are static methods working on static array. Lock the array object!!! See sample
code snippet below.

static Object[] ary = new Object[50];


static void method1() {
System.out.println("do something not need to lock the ary...");
synchronized(ary){
System.out.println("do something on ary Object..");
try{
ary.wait();
}
catch(InterruptedException e) {
}
System.out.println("do something else on ary Object..");
}
System.out.println("do something else not need to lock the
ary...");
}

Q. What is race condition?


A:

Quote from The Java Tutorial:


Race conditions arise from multiple, asynchronously executing threads try to access a
single object at the same time and getting the wrong result.

An excellent explanation of race condition here! Not Java specific!!!


http://www.kulua.org/Archives/kulua-l/199901/msg00025.html

Q. What is Thread Deadlock? How to avoid it?


A:
A deadlock occurs when one object is waiting for another to release a lock, and that
object is also waiting. A circular dependency occurs, and then the waiting thread will
wait forever, or deadlocked.The key to prevent deadlock: Do not hold a lock while
waiting another resource that also requires locking.Read from Sun's tutorial:
http://java.sun.com/docs/books/tutorial/essential/threads/deadlock.html
Play with the famous Dining Philosopher Problem (not invented by Java!) Applet and
learn the important concepts when you have fun.

• What is Thread Starvation? What causes it? How to avoid it?

Q. What is Thread Starvation? How to avoid it?


A:
For any reason, one or more threads never get a chance to run, or be blocked for a long
time if not forever.Many reasons can cause Thread starvation:

1. Threads are deadlocked.


2. Thread is blocked by I/O, the I/O never become available again.
3. Other threads with higher priority run selfishly, never give other thread a chance
to run.
4. Synchronized methods/blocks forget to release the lock/monitor. In Java,
wrongfully using sleep/yield instead of wait/notify/notifyAll has a very good
chance to cause deadlock/starvation.
5. Your Thread scheduling system does not working correctly.
6. ...

How to avoid/correct them? Find out what causes your thread starvation, and correct
them.

Q. When a Thread die? Can a dead Thread be restarted?


A: No. a dead Thread cannot be restarted.

• If you call its start() method after its death, IllegalThreadStateException will be
thrown.
• Even the Thread is dead, but you still can call its other method. Why? Simple, the
Thread is just another Java Object. For example, if you call its run() method
again, it will be just a sequential procedure call, no concurrent execution at all.
• The exit() method of class Runtime has been called and the security manager has
permitted the exit operation to take place.
• Non daemon threads die, either by returning from call of the run() method or by
throwing an exception that propagates beyond the run() method.
• Daemon Threads die when all user Threads died.

Q. When will a Thread I/O blocked?


A:
When a thread executes a read() call on an InputStream, if no byte is available. The
calling Thread blocks, in other words, stops executing until a byte is available or the
Thread is interrupted.

Serialization

Q. What class can be serialized? What cannot?


A:
Almost all JDK classes are serializable except

• Classes with only static and/or transient fields. For example, Math, Arrays, etc.
• Classes representing specifics of a virtual machine. For example, Thread, Process,
Runtime, almost all classes in the java.io and many classes in java.net packages
are not serializable

I/O Streams, Reader/Writer

Q. Creating a File object does not mean creation of any file or directory, and then when
does the creation of physical file take place?
A: The answer is it depends...
The physical file might be created 10 years ago by one of your long gone colleagues ,
or will be created on the next step of running when your program tries to write something
onto the not-yet-exist file by using FileOutputStream or FileWriter.

You can also call createNewFile() of the java.io.File object to create a new, empty file
named by its abstract pathname if and only if a file with this name does not yet exist.

The file might never be created since the program does not have write permission (of
java.io.FilePermission) in that specified directory.

The file might never be created simply because the program never try to do anything on
it, absentminded programmer, of course.

The java.io.File object might just represent a directory, which might not be a file at all.

Read The Java Tutorial It is free. Read javadoc, and compare the exception thrown by
File and FileWriter constructors will help as well.
To the top

Q. Is it possible to change directory by using File object?


A:
No, You cannot change the directory by using a file object.

Instances of the File class are immutable; that is, once created, the abstract pathname
represented by a File object will never change.

However, you can use one File object to find the directory you want, and then create
another File object for the directory you want to go to.
To the top

Q. How to create a new directory by using File object?


A:
Using class File method mkdir() or mkdirs(). See code here:
// MakeDir.java
import java.io.*;

public class MakeDir {


public static void main(String args[]){
// make sure sub-directory "mmm" does not exist
File dir=new File("mmm");
System.out.println(dir.mkdir());// true

// make sure at least two of "hhh\\lll\\nnn" does not exist


File multidir=new File("hhh\\lll\\nnn");
System.out.println(multidir.mkdir()); // false
System.out.println(multidir.mkdirs()); // true

// make sure at least two of "..\\ccc\\ddd\\eee" does not exist


File updir=new File("..\\ccc\\ddd\\eee");
System.out.println(updir.mkdir()); // false
System.out.println(updir.mkdirs()); // true

// If you run the code second time,


// the result will be different. Why?
}
}
To the top

Q. What are the differences between FileInputStream/FileOutputStream and


RandomAccessFile? Do you have a good example on it?
A:
Remember never mixing RandomAccessFile with Streams!!! RandomAccessFile class is
more or less a legacy from c language, the Stream concepts/C++ were not invented then.

This example deals with File, FileInputStream, DataOutputStream, RandomAccessFile.


Play with it; try to understand every bit of the output. IOTest.java

Q. What are the difference between File.getAbsolutePath() and


File.getCanonicalPath()? Can they return different result?
A: Find your answer by reading this:
http://java.sun.com/j2se/1.3/docs/api/java/io/File.html

Yes, they can return different results! See the following example. Pay attention to the
comments.
import java.io.*;

public class T
{
static void testPath(){
File f1 = new File("/home/jc/../rz/rz.zip"); // file does not exist
File f2 = new File("T.class"); // file in rz dir under
/home/rzhang
// no try/catch block needed
// return "/home/jc/../rz/rz.zip" always
System.out.println("Absolute path for f1: " +
f1.getAbsolutePath());
// return "/home/rzhang/rz/T.class"
System.out.println("Absolute path for f2: " +
f2.getAbsolutePath());

try {
// not compilable if neither try/catch block nor throws present
// return "/home/rz/rz.zip"
System.out.println("Canonical path for f1: " +
f1.getCanonicalPath());

// return "/home/rzhang/rz/T.class"
System.out.println("Canonical path for f2: " +
f2.getCanonicalPath());
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}

public static void main(String[] args){


T.testPath();
}
}
To the top

Q. Which one of the following will create an InputStreamReader correctly?

1. new InputStreamReader(new FileInputStream("data"));


2. new InputStreamReader(new FileReader("data"));
3. new InputStreamReader(new BufferedReader("data"));
4. new InputStreamReader("data");
5. new InputStreamReader(System.in);

A:
The leagal constructors for InputStreamReader are
InputStreamReader(InputStream in)
InputStreamReader(InputStream in, String enc)

1. If you compile this line without a try/catch block, you will get a compile error:
Exception java.io.FileNotFoundException must be caught, or it must be declared
in the throws clause of this method.

How to do it correctly?
2. try {
3. new InputStreamReader(new FileInputStream("data"));
4. }
5. catch (java.io.FileNotFoundException fnfe) {
6. }

Answer: If they let you choose one, choose e. If they let you choose two, choose a
and e.

7. Error #1: FileReader is not an InputStream.


Error #2: The same problems as a), Exception java.io.FileNotFoundException
must be caught
8. Error #1: BufferedReader is not an InputStream. Error #2: There is no contructor
of BufferedReader to take string as argument.
9. String "data" is not an InputStream.
10. Correct, since System.in is an InputStream.

To the top

Q. Why only read() methods in ByteArrayInputStream does not throw


IOException?
A:
You are right, read() methods of all other InputStreams throw IOException except
ByteArrayInputStream.

This is because the entire byte array is in memory; there is no circumstance in which an
IOException is possible.

However, close() and reset() methods of ByteArrayInputStream still can throw


IOException.

Q. How does InputStream.read() method work? Can you give me some sample
code?
A:
Here is the sample code; the explanation is in the comments. Make sure you compile it,
run it, and try to understand it.
// TestRead.java
import java.io.*;
public class TestRead {
public static void main(String argv[]) {
try {
byte[] bary = new byte[]{-1, 0, 12, 23, 56, 98, 23, 127, -128};
ByteArrayInputStream bais = new ByteArrayInputStream(bary);
System.out.print("{ ");
while (test(bais)){
System.out.print(", ");
}
System.out.println(" }");
// output: { 255, 0, 12, 23, 56, 98, 23, 127, 128, -1 }
// Notice 2 negative byte value becomes positive
// -1 is added to the end to signal EOF.
}
catch (IOException e) {
System.out.println(e);
}
}
public static boolean test(InputStream is) throws IOException {
// Read one byte at a time and
// put it at the lower order byte of an int
// That is why the int value will be always positive
// unless EOF, which will be -1
int value = is.read();
System.out.print(value);

// return true as long as value is not -1


return value == (value & 0xff);
}
}
To the top

Q. How to read data from socket? What is the correct selection for the question?
A socket object (s) has been created and connected to a standard
Internet service
on a remote network server.
Which of the following gives suitable means for reading ASCII data,
one line at a time from the socket?
A. s.getInputStream();
B. new DataInputStream(s.getInputStream());
C. new ByteArrayInputStream(s.getInputStream());
D. new BufferedReader(new InputStreamReader(s.getInputStream()));
E. new BufferedReader(new
InputStreamReader(s.getInputStream()),"8859-1");
A:
A. InputStream does not readLine()
B. DataInputStream.reaLine() deprecated
C. ByteArrayInputStream does not readLine()
D. the only correct answer.
E. encoding put in the wrong place. The correct way is
new BufferedReader(new InputStreamReader(s.getInputStream(), "8859-
1"));
See sample from the Sun: Reading from and Writing to a Socket
To the top

Q. How to use ObjectOutputStream/ObjectInputStream?


A:
A sample code here, which writes to ObjectOutputStream, and reads it back from
ObjectInputStream. The program not only deals with instance object, but also Class
object. In addition, it uses reflection to analyze how it works.

Find it at TestSerialization.java Pretty heavy i/o, serialization, reflection, transient/static


stuff, if it is too over your head, skip it.
To the top

Q. How to compare two (binary/not) files to see if they are identical?


A:
1) Open 2 streams
2) Compare their length first, if not the same, done
3) If the same lengths, then compare byte to byte, until you find anything not the same, or
end-of-file
4) You get your answer
Q. When I use the following code to write to a file, why the file has no data in it?
// WriteFile.java
import java.io.*;
public class WriteFile {
public static void main(String[]args)throws Exception {
FileOutputStream fos = new FileOutputStream("out.txt");
PrintWriter pw = new PrintWriter(fos);
pw.print(true);
pw.println("short content file");
}
}
A:
When you open out.txt, it is an empty file, correct. Try to write a lot of text on to the file,
and then you get something back, but not all of them.

Why? The reason is for efficiency, the JVM or OS tries to buffer the data to reduce the
hit of hard disk or other media. If you do not flush and close, the data might be lost.

I remember when I was coding in Pascal (C?), I had exact the same problem. I learned a
lesson that always closing you file or stream after finishing read/write to it.

If you change you code to the forlowing, everything will be ok!


// WriteFile.java
import java.io.*;
public class WriteFile {
public static void main(String[]args)throws Exception {
FileOutputStream fos = new FileOutputStream("out.txt");
PrintWriter pw = new PrintWriter(fos);
pw.print(true);
pw.println("short content file");
pw.close();
fos.close();
}
}
To the top

Garbage Collection

Q. Are there any differences between these two code pieces?


ArrayList al=new ArrayList();
Student s1 = new Student("abc");
al.add(s1);
// Or use the following instead
// al.add(new student("abc");
A: Yes, Differences on object access, also on GC.
They are the same from you adding a student object to the ArrayList of view. However,
the student has another reference s1 point to it, you can use it to access the student other
than from the ArrayList. From GC point of view, they are very different, if you set the
ArrayList al to null, the student object cannot be GCed unless you also set s1 to null.
To the top
Q. Will finalize method of all objects eventually be called?
A: The answer is yes, with an exception of JVM being killed abruptly for internal or
external reasons.
If the your application is terminated normally, the finalize method of all objects
eventually will be called. The simlest way to prove it would be writing a very small
application with a few objects instantialized. All objects in your application have a
finalize method with a println("XXX object finalize method is called now.");
in it. Run it and see the result. This is because JVM will take care of it before normal exit.
All objects are eligible for GC and will be GCed before JVM terminates. Of course, we
are not considering the special case that JVM might have a bug. :)

However, what is the exception?

• JVM is killed internally, by


1. System.exit(1);
2. Uncaught Exception being thrown at the top level.
3. You may add more...
• JVM is killed externally, by
1. User use ctrl C or other system commands to kill it on windows, unix, or
...
2. System power off.
3. You may add more...

To the top

Q. Any class that includes a finalize method should invoke its superclass' finalize
method, why?
A:
The point is that finalize methods are not automatically "chained" - if you subclass a class
that has an important finalize, your finalize method should call it. Obviously if you don't
know what the superclass finalize method does, you should call it anyway, just to be safe.

By contrast, When you create an object with the new keyword, the superclass
constructor(s) are called first. This is automatically "chained".

Q. When an object becomes eligible for garbage collection?


A:
The object is no longer referenced or referenced only by objects, which are eligible
for GC.An object becomes eligible for garbage collection when there is no way for any
active thread to reach that object through a reference or chain of references. (An
equivalent answer by Jim Yingst)Set all references to an object to null is sufficient for an
object eligible to GC, but not necessary.

Here are two simple examples with proper comments:


public class Test1{
public static void main(String[] args) {
Object a = new Object();
Object b = a;
a = null;
// the Object is still referred by b.
// which is not eligible for garbage collection.

// an infinite loop here


int i = 0;
while (true){
i = i++;
}
//Using ctrl C to kill it, sorry!
}
}

public class Test2{


public static void main(String[] args) {
Object[] ary = new Object[5];
for (int i=0; i<5; i++) {
ary[i] = new Object();
}

// do something here

ary = null;
//Now all objects in the array are eligible for GC
// even none of their references are null.
}
}
To the top

Q. Can circular reference prevent objects from be garbage collected?


A: No! Prove by counter example:
class Test1 {
public static void main(String arg[]) throws Exception{

MyObj a = new MyObj("a");


MyObj b = new MyObj("b");

//circular reference here


a.o = b;
b.o = a;

a = null;
b = null;
// a and b are both eligible for GC now

MyObj c = new MyObj("c");


c.o = new MyObj("d"); //when c dies, d dies too.
c = null;

// an infinite loop here


// use ^c to kill it

MyObj[] objAry = new MyObj[1024];


int i = 0;
while (true){
// suggest JVM to GC
System.gc();

// use more memory here


i %= 1024;
objAry[i] = new MyObj("X" + i);

i++;
Thread.sleep(5); // Give CPU some breath time
}
}
}

class MyObj {
MyObj o;
String s;
long[] ary = new long[4096]; // make MyObj big

MyObj(String s) {
this.s = s;
}

protected void finalize() throws Throwable {


// Make GC visible
System.out.println(s + ": I am dying");
super.finalize();
}
}
To the top

Q. How many objects are eligible for GC in the following code after d = null?
public class Test{
public static void main(String[] args) {
Object a = new Object(); // the object original referenced by
object reference a
Object b = new Object();
Object c = new Object();
Object d = new Object();

d=c=b=a;
d=null;
}
}
A:
Just remember that operator = is right associate, and then you should be able to figure
out the answer by yourself. The equivalent statement is d=(c=(b=a)); The example in
here following can be used to get the answer you need too, minor change required.
Answer: Three.
1) After b=a, the object original referenced by b is eligible for GC.
2) After c=(b=a), the object original referenced by c is eligible for GC.
3) After d=(c=(b=a)), the object original referenced by d is eligible for GC.
4) After d=null, nothing new is eligible for GC.
5) The object original referenced by a is not eligible for GC, since it is still referred by
references a, b, c. 6) Make sure you understand the differences between physical object
and object reference (pointer to object).
To the top

Q. When the object created in the code will be garbage collected?


public Object m() {
Object o = new Float(3.14F);
Object [] oa = new Object[1];
oa[0] = o;
o = null;
return oa[0];
}
A:
To the top

Q. In garbage collection mechanism, what is vendor/platform dependent? What is


not?
A:
How GC implemented is vender and platform dependent. Which means:

It is vender and platform dependent that when and in what order the eligible for
GC objects will be GCed.

However, which objects are eligible for GC is independent of implementations. Different


vendor may use different algorithms. What algorithm used to find the objects, which are
eligible for GC does not matter. What really matters is that they use the same principle.

The object is no longer referenced or referenced only by objects, which are eligible
for GC.

Unless they have a bug...

Q. Can an object be garbage collected, but a field of it is still alive?


A: Sure, as long as it is still referred by something.
Actually, this is used by many design patterns, e.g. Factory Method pattern. See the
following example, read the comments carefully!
// UseSimple.java
class Simple {
void writeSomething(String msg) {
System.out.println("Simple.writeSomething: " + msg);
}
protected void finalize()throws Throwable{
System.out.println("Finalize:Simple");
super.finalize();
}
}

class CombineSimple{
private Simple simFld;

Simple getSimpleField() {
if( simFld == null ) {
simFld = new Simple();
}
return simFld;
}
protected void finalize()throws Throwable{
System.out.println("Finalize:CombineSimple");
super.finalize();
}
}

public class UseSimple {


public static void main(String[] args) {
CombineSimple csObj = new CombineSimple();
Simple simObj = csObj.getSimpleField();

csObj = null;

// Since GC cannot be forced


// we make sure csObj is GCed.
System.gc();
for (int i=0; i<3; i++){
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
System.gc();
}

// The simFld field of csObj will be still alive


// since it is still referred by simObj
simObj.writeSomething("I am still alive!");
}
}
To the top

Q. What is mark and sweep garbage collection algorithm, is there other algorithms?
A:
The question is out of the scope of SCJP, however, it will help you in job-hunting
process. Here is a beautiful applet, which will give you the basics, and have fun: Heap of
Fish, A Simulation of a Garbage-Collected Heap
To the top
Exception Handling

Q. When we override or hide a method in superclass, we can throw more exceptions,


or less?
A: The same or less!
According to JLS8.4.6 "A method that overrides or hides another method (§8.4.8),
including methods that implement abstract methods defined in interfaces, may not be
declared to throw more checked exceptions than the overridden or hidden method."

See an example below, pay attention to the comments and commented out code.

class Ex1 extends Exception {}


class Ex2 extends Exception {}
class Ex3 extends Exception {}

class Base {
void method1() throws Ex1, Ex2 {
// some code which might throw Ex1 and/or Ex2
}
void method2() throws Ex3 {
// some code which might throw Ex3
}
}

class Sub1 extends Base {


// allow throwing less exceptions
// since it does not violate the contract of Base.method1()
void method1() throws Ex1 {
// some code which might throw Ex1 and/or Ex2
}

// Not compilable, since throw more or different exceptions


// Sub1 is a Base, violate the contract of Base.method2() is not
allowed
// void method2() throws Ex1, Ex3 {
// some code which might throw Ex1, Ex3
// }
}

To the top

Q. I have an example of a source code that it started with "import Exceptions.*;". Is


there such a package?
A:
Anybody can define any packages.
Answer: Possible If your question is "Is there such a package in JDK1.2.2?"
Answer: No.BTW, Sun's convention: package name starts with a lowercase letter.
To the top

Q. Can no argument constructor throw exception?


A: Yes, see the following code
public class A {
public A() throws Exception {
throw new Exception("No argu constructor can throw exception
too");
}
public static void main(String args[]) {
try {
new A();
}
catch (Exception e) {
System.out.println(e);
}
}
}
To the top

Q. What should I do to catch all exceptions in my code?


A: You catch all of them, period.
Here is 2 examples, the first one is bruital force way, not good, but serve your purpose.
The second is considered as a good code practice.
// 1. The brutal force way
try {
// do something...
}
catch (Exception e) {
e.printStackTrace();
}

// 2. catch the most specific exception first


try {
// do something...
}
catch (IOException ioe) {
ioe.printStackTrace();
}
catch (SomeOtherException soe) {
soe.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}

To the top

Q. Is finally always been called? Do you have a good example?


A: Yes.
An interesting example.

Q. When I have two exceptions thrown in the same try block, when the first exeption is
thrown, the second exception is ignored. Why?
A:
The concepts you really need to understand are:

An exception is thrown, which means the code cannot continue its normal path. The
later code will not be excuted no mater there is another throw exception statement
or not. This bad situation will continue until the thrown exception is caught or the
program will die at the top level.
To the top

Q. Is there a way to make static method not available according to some runtime
condition?
A:
Yes! See the following code snippet:
class UtilClass{
static boolean condition;
static {
// init condition at runtime
}
public static void staticMethod() throws Exception{
if (!condition) {
throw new Exception("method not supported for...");
}
// do your job
}
}
To the top

Q. Why the method can be compiled without a return? What will happen if return
is added?
class Test {
static int oops(int i) throws Exception {
throw new Exception("oops");

// compile error
// unreachable code
// return 5;
}
}
A:
All this code does is throw an Exception. If you put return there as the commented code,
compile error results.
Attention: never, ever write this code in your job. Here is for proof of concepts only.

Q. Checked exception must be caught or declared, how about unchecked ones?


A:
Checked exception must be caught or declared in the method throws statement.
Unchecked Exception is not required to do the same. However, if you do, it does not
cause an error either.Something must be specified does not imply Something else must
not be specified The preferred way to deal with unchecked exception is put in javadoc,
give programmer a warning.
To the top

Q. Why RuntimeException or unchecked exception don't need to be caught or


thrown explicitly in Java code?
A: I usually don't answer why questions, but this is an Exception!
RuntimeException is a kind of unpredictable, or say it can happen anywhere/everywhere.

For example: NullPointerException can happen anywhere as long as you have an Object
o, and code like

o.doSomething();
o.someField = somthing;

It could possiblely throw NullPointerException.

Another example is an array, whenever you use array[n], It could possiblely throw
ArrayIndexOutOfBoundsException.
Do you really want to put try/catch all the possible runtime exceptions everywhere?

Generic catch block


catch (Exception e){
}
is generally prohibited by most coding standards.
To the top

Pass by Value, etc

Q. What does it mean by saying that "In Java, every thing is passing by value"?
A:
Pass-by-Value is opposed to pass-by-reference, pass-by-name, etc.A discussion, sample
code, Sun's and other language theory references can be found at
PassByValueEx.JavaHowever, in RMI, the remote object actually is passed by using the
whole object including all objects it referenced as value through serialization. However,
this is beyond the scope of SCJP. See details at Fundamentals of RMI
To the top

Q. Another good pass-by-value example, useful and practical.


A:
Copy the code, compile it, run it, see the results. Read the comments carefully. If you still
don't understand, see the above question and follow the link. More information,
explanation there. Sun's and other language theory references are provided.
// PassByValueTest.java
public class PassByValueTest {
public static void main(String [] args) {
String arr[]=new String[2];

arr[0]="hello";
arr[1]="hi";

// nothing will change here


swap(arr[0], arr[1]);
System.out.println(arr[0] + ", " + arr[1]); //hello, hi

// two Strings are actually swapped


swap(arr, 0, 1);
System.out.println(arr[0] + ", " + arr[1]); //hi, hello
}

// useless swap method, since you swap the copies


// of two strings' reference inside the method
// Strings outside are not affected.
public static void swap(String s1,String s2){
String tmp = null;

tmp = s1;
s1 = s2;
s2 = tmp;
}

// real practical swap here


// swap array elements with two indices
// very useful for sorting algorithm, etc.
// reference of arr will never change (pass-by-value)
// but the contents of arr will change permanently
// since the copy of arr reference still refer to the same object.
public static void swap(String arr[], int ix1, int ix2) {
String tmp = null;

tmp = arr[ix1];
arr[ix1] = arr[ix2];
arr[ix2] = tmp;
}
}
To the top

Q. What is the differences between pass-by-value and pass-by-reference?


A: These two will never mix!!!
Pass-by-value : You make a copy of the parameter (argument), and use it inside of the
methods. The value of the parameter (argument) will not be affected outside of the
method.Pass-by-references : you do NOT make a copy of the parameter, you use the
parameter itself!
Q. Why we say, in c or Java, everything is pass-by-value?
A:
In c and Java, everything is pass-by-value. In c++ and Pascal, you can pass-by-value or
pass-by-reference.When we code in C, you pass pointers to a method, the value of pointer
(address) will never change, but the value the pointer points to will change. In language
theory, C is a only-pass-by-value language. Actually, this is exactly Java does. Java
Object reference is equivalent to C pointer, the difference is you cannot dereference it,
which makes java safer, but less flexible.Since in C, you can dereference a pointer, you
actually can prove the pointer is passed by value. A simple test can prove that, you
dereference the pointer inside/outside the method call, you will get two different values,
which proves inside the method, what we are using actually a copy of the pointer, not the
pointer itself.That is exactly what pass-by-value means. You make a copy of the
parameter (argument), and use it inside of the methods. The value of the parameter
(argument) will not be affected outside of the method.In Java, value of an object
reference is the reference. That is the source of confusion. However, if you read it
twice, it only makes sense. Doesn't it?

To the top

Q. Can you provide some authoritative quotation to support the saying "In Java,
everything is pass-by-value"?
A:
From The Java Programming Language, by James Gosling et al. 3rd edition (pg. 56):
quote:

Some people will say incorrectly that objects are passed "by reference." In programming
language design, the term pass by reference properly means that when an argument is
passed to a function, the invoked function gets a reference to the original value, not a
copy of its value. If the function modifies its parameter, the value in the calling code will
be changed because the argument and parameter use the same slot in memory. The Java
programming language does not pass objects by reference; it passes object references by
value. Because two copies of the same reference refer to the same actual object, changes
made through one reference variable are visible through the other. There is exactly one
parameter passing mode -- pass by value -- and that helps keep things simple.

From The Java Tutorial


quote:

Pass by Value

In Java methods, arguments are passed by value.


When invoked, the method receives the value of the variable passed in. When the
argument is of primitive type, pass-by-value means that the method cannot change
its value. When the argument is of reference type, pass-by-value means that the
method cannot change the object reference, but can invoke the object's methods
and modify the accessible variables within the object.
This is often the
source of confusion--a rogrammer writes a method that attempts to modify the
value of one its arguments and the method doesn't work as expected. Let's look
at such method and then investigate how to change it so that it does what the
programmer originally intended.

Quiz question from Sun:


In Java programming, all method parameters are passed by value.
Answer: true In Java, everything is pass-by-value, unless you think Dr. James Gosling
forgot how he invented Java, AND Sun does not know how Java works.If we all agree
those are not the cases. Then the question should change to that how to understand the
fact "In Java, everything is pass-by-value".If you go up-and-down a little, you will find a
lot of help here.
To the top

Q. What can I do in Java, if I want to use the C++ like pass-by-reference?


A:
Java and C languages simply do not support pass-by-reference. They only support
pass-by-value.

C++ and Pascal languages support both pass-by-value and pass-by-reference.

Ada language supports probably three, pass-by-value, pass-by-reference, and pass-by-


name. Fortran language only support one, pass-by-reference. As far as I could recall, I
might be wrong on these two. Don't have time and desire to check them out anymore.

Those are language designers' choices. As a language user like you and me, we cannot do
anything about it. What we can do is vote by our keyboard, select the language we
like to code...

To the top

Q. Is there any programming language, which use pass-by-reference only?


A:
The first, and still the most efficient high level programming language is FORTRAN. As
far as I can recall, it is everything pass-by-reference. FORTRAN is not dead, it is still
alive. Is it amazing?! In NASA, the space center of USA, the most used programming
languages are still FORTRAN and Ada, it is them sending men on the moon.
To the top

Some Java utilities, tools

Q. What is javap?
A:
A Java utility officially called Java Class File Disassembler. It can disassemble your
class by type:
javap -c Test$1
You must have compiled class Test$1.class before using it. See an interesting use of
javap disassembler example here.

However, javap is commonly used as a kind of profiler, which profiles your class. It
generates something similar to c/c++ *.h file, if you use no option or options like -
privateIf you were c/c++ programmer in your previous life , and missed the *.h file
convenience, then you have a utility to do the job for you. Who says the life is not
beautiful? See javap - The Java Class File Disassembler for more options and details.

To the top

Q. Why some code is perfect fine according to Java Language Specification(JLS),


but not compilable by javac?
"An instance initializer of a named class may not throw a checked exception unless that
exception is explicitly declared in the throws clause of each constructor of its class and
the class has at least one explicitly declared constructor." --from JLS2
A:
Some Java code is perfect fine according to Java Language specification(JLS), but not
fine to jdk1.2.2 javac compiler, since javac is not strictly compliant with JLS. It sounds
strange, but it is the fact.There is a compiler which is 100% compliant with JLS: jikes.exe
from IBM. Jikes.exe is jdk version independent too. No matter which version of jdk
you're using, as long as your give your jar files classpath correctly, it will compile
correctly for you. If you find jikes anything not compliant with JLS, you can report or fix
it too, since it is open source. See the following link for more about jikes:
http://oss.software.ibm.com/developerworks/opensource/jikes/project/index.htmlThe
following code is not compilable by javac, but perfectly compilable by jikes and runnable
by java:
class SmpException extends Exception {}
public class InstInitTest {
int k, l;
{
k = 10;
System.out.println("It's ok to JLS, but it isn't ok to javac
compiler");
if (k > 0)
throw new SmpException();
l = k;
}
public InstInitTest() throws SmpException{}
public static void main(String[] args) {
try {
new InstInitTest();
} catch (SmpException e){}
}
}
Attention: Sun finally fixed this problem in j2sdk1.4!!!
To the top
Q. What are the differences between JVM (java virtual machine) and JRE (java
runtime environment)?
A:
The JRE package is intended for distribution with applications. It does not contain the
tools.jar file that has the compiler and other command line tools. The reason Sun makes
the distinction is to give developers a more compact set of files to distribute with a
product.Also, JVM is the more generic name which can apply to any program which
obeys the Java Virtual Machine Specification - whether it's made by Sun, IBM,
Microsoft, or whoever. JRE on the other hand is the name for Sun's implementation of a
JVM.Even j2sdk is free, but it is illegal to distribute j2sdk with your product. Therefore if
your product required j2sdk to run. Then you must require your client to download it
from Sun and install it before instalation of your product. What a headache! On the
opposite, you can distribute JRE with your application freely.
To the top

Q. Which Java GUI builder is better?


A:
I don't use gui builders in Java, since most of them are cumbersome, slow, hard to use,
when you change them to GridBagLayout, then you are stucked, hard to change again.
There is no comparison with VB or VC++ GUI builders. Those are light weight, intuitive,
easy to use. You can change the result by GUI builder, or by hand. After your changes by
hand, the GUI builder will pick them up correctly. They can generate code or you can
write yourself, the code from different writers does not fight with each other. In addition,
they are fast and not memory hogs. I could say this since I'd worked with them for a long
period of time. I've heard the open source C# IDE has already better than any commercial
Java IDEs. Sorry for us!In my previous job, my boss was a big IDE fan, and we were
using VAJ, with all the "Java IDE features" I mentioned above. I used VAJ to generate
the GUI for our main screen, the code with no additional logic was about 1000 lines; I've
not counted all the stupid binary stuff they generated to remember the GUIs. I needed to
customize it a little by hand, then the entire system was broken. I decided to write it
totally by hand include the logic, it only costed me a little more than 300 lines, and did
more job than the original 1000 lines. The code was human readable and easy to
maintain. My boss was kind of unhappy with me since I did not use IDE. However, he
did not argue the fact I did much better and faster job than the IDE. Of course, you could
argue, I was not proficient enough on VAJ, and that was very true too. However, you
cannot argue the fact I can build GUI without any IDE and real fast. These are only my
personal experiences. I also know a lot of people who like JBuilder or something else
very much.
To the top

Q. Can you recommend a Java decompiler?


A: jad is the best I know off.
Many conmercial ones are either based on jad, or less good than jad, with a fancy GUI, of
course. jad is available free here.
To the top
Java Left-to-right rule of evaluation

Q. int x = 0; x=x++; System.out.println(x); The output is 0 instead of 1. Why?


A:
I do know the answer and you need to know how the Java compiler parser works. But my
advice is:
Please do not write code like this. Otherwise, you will be fired immediately by
almost any boss. I used to test something similar (a little more complicated stuff) in C
language, Borland, Microsoft, and Unix cc gave me 3 different answers. More
interestingly, Microsoft VC++ gave me 2 different answers in their debug and release
version. Fortunately, javac and jikes gave me the same answer. Java does have a rule on
this. It is called evaluating from left to right. If you really want to know how the rule
works, play a lot of examples, then you might get it. You will waste a lot of time. Then
after 2 hours or 2 days or ..., most probably, you are confused again. No matter you are
new or experienced in Java, you are better-off by not knowing the answer. It will not
affect you pass the SCJP. I really hope that people will not give various guess-based
answers here. What if I cannot fall in sleep if I don't know how this works? Here we
are:
The rule "Evaluating from left to right" is for resolving the addresses
and evaluation of expression.
It works this way:

int x = 0;
x = x++;
1) Get value of x (0 for now), put it somewhere
2) increase the value of x (x value is 1 now)
3) assign the value stored somewhere back to x (x value is 0 again)

A better example to illustrate the concepts is:

int y = 5;
int y = y++ + y++; //(the y value will be 11)

1) Get value of 1st y (5 for now), put it somewhere


2) increase value of y (y value is 6 now)
3) Get value of the 2nd y (6 for now), put it somewhereelse
4) increase value of y (y value is 7 now)
Attention: from 1 to 4 is strictly left to right.
The evaluation of the right hand side expression is finished now.
See Mughal and Rasmussen's book for details.
However, there is no such rule in C language.

5) adding the value in somewhere and somewhereelse together


assign it to y
(y = 5 + 6 = 11)
Finally, I figured out a way to prove the Evaluating from left to right rule without
violating the HEISENBERG uncertainty principle If you are from Copenhagen,
Denmark, or you are/were a physicist/chemist, you probably know what I'm talking
about. The principle is conceptually "You cannot measure a system without disturbing
the system." If you want the original words from Heisenberg, go to the above link to find
out. They will look very different, but really mean the same thing. We are in Java or CS,
so I found a way to measure the system without disturbing the system. Now you can
see the evaluating from left to right at work and test any of your doubt here using
FromLeftToRight.java
To the top

Q. Why the following code does not throw IndexOutOfBoundsException, and print
out 9 9 6?
class ArrTest{
public static void main(String args[]) {
int i = 0;
int[] a = {3,6};
a[i] = i = 9;
System.out.println(i + " " + a[0] + " " + a[1]); // 9 9 6
}
}
A:
This is another good example the great Java evaluation rule applies. Java resolves the
addresses from left to right. a[i] which is the address of a[0], then i which is the address
of i, then assign 9 to i, then assign 9 to a[0]. IndexOutOfBoundsException will never be
throw since a[0] is not out of bound. The misconception is a[9], which is against the left-
to-right-rule.See more about Left-to-right-rule stuff from the above question, if you're too
curious about it. Otherwise, pass!
To the top

Q. Why the following code print out "BAC", instead of "ABC"?


// C.java
class C {
public static void main(String arg[]) {
System.out.println("A"+new C());
}
public String toString() {
System.out.print("B");
return "C";
}
}
// output:
// BAC
A: You need understand 2 concepts here: Java left-to-right evaluation rule and side effect.
If you don't know what is Java left-to-right evaluation rule, read the above 2
question/answer pairs first.Java evaluates the expression
"A"+new C()
following the same rule. It gets "A" first, which is a String literal, put it somewhere. Then
it evaluate
new C()
it construct a C Object first, then invoke toString() method of C Object, and gets the
value of C object, which is "C", then concatenates "A" and "C" together, and println
"AC".Where does "B" come from? Inside the toString() method of C Object, there is a
System.out.print("B");
which is invoked when Java evaluate the above expression. It is printed out before the
evaluation completed. That is why "B" is printed first.In CS terms, it is called side effect.
It is generally considered bad coding style. You are surprised, aren't you? Nobody in their
right mind should expect toString() method will actually print something unless it is for
debug purposes.Follow the rule of KISS (Keep It Simple and Stupid/Straight
forward), please!!

Bitshift, binary operators

Q. Any suggestion on learning bitwise operator?


A: Excellent tutorial and games, play and have fun!

1. Bin Dec Hex Tutorial


2. BitShift, an applet to let you see the conversion and operation
3. Cat and Mouse Games with Bits, a beautiful game teaches you how bits work.

To the top

Q. Why ~3 gives -4?


A:
Don't forget in Java, except char, every number is signed. And the sign bit is inverted too.
That is why you get -4 for answer.
Spaces added for readbility.
~3 is ~(0000 0000 0000 0000 0000 0000 0000 0011)
or 1111 1111 1111 1111 1111 1111 1111 1100
which is -4 What you really need to learn is called
Two's compliment Read it, it is an excellent article, I learned a lot from it!
To the top

Q. Why does -54 does not become positive after right shift?
A:
>> is a signed shift, that means the sign bit will stay there after right shift. In other words,
fill all the spaces produced by the shift by the original sign.On the opposite, >>> is an
unsigned shift; zero will fill all the spaces no matter what is the original sign.
public class A {
public static void main(String[] args) {

int x = -54; //11111111111111111111111111001010

//sign fill the first two bits


int y = x >> 2; //11111111111111111111111111110010

System.out.println("y = " + y); //-14

// zero fill the first two bits


int z =x >>> 2; //00111111111111111111111111110010
System.out.println("z = " + z); //1073741810

System.out.println("x = " + Integer.toBinaryString(x));


System.out.println("y = " + Integer.toBinaryString(y));
System.out.println("z = " + Integer.toBinaryString(z));
}
}
To the top

Q. Is long valid operand for shift operators? What are the rules for shift promotion?
A: Yes, long is valid shift operand(s). The rules can be found from JLS 5.6.1
Read the JLS 5.6.1 at least twice, or until you understand.
The following example will help you to digest. Read the comments, please!
public class ShiftPromotion {
public static void main (String [] args) {
long longNum = -64;
long longDist = 4;
int intNum = -64;
int intDist = 4;
byte byteNum = -64;
byte byteDist = 4;

// both int and long are valid operand


int intResult = intNum >>> intDist;
long longResult = longNum >>> longDist;

System.out.println("intResult = " + intResult); // 268435452


System.out.println("longResult = " + longResult); //
1152921504606846972

// Unary promotion here!


// byte, char, short will be promoted to int individually
// otherwise, as is.

// not compilable
// byte byteResult = byteNum >>> byteDist;

intResult = byteNum >>> intDist;


System.out.println("intResult = " + intResult); // 268435452

intResult = byteNum >>> byteDist;


System.out.println("intResult = " + intResult); // 268435452

longResult = longNum >>> byteDist;


System.out.println("longResult = " + longResult); //
1152921504606846972

// Unary promotion here!


// longDist will not promote intNum to long
intResult = intNum >>> longDist;
System.out.println("intResult = " + intResult); // 268435452
}
}
To the top
Q. Is negative number still negative after leftshift?
A: No, not necessarily.
The original sign bit is always fall off the cliff; the sign of the new number will depend
on the new first bit being shifted there.See the following example:
-1073741825 << 1 in decimal
0xBFFFFFFF << 1 in hexadecimal
1011 1111 1111 1111 1111 1111 1111 1111 << 1 in binary
0111 1111 1111 1111 1111 1111 1111 1110 after shift in binary
0x7FFFFFFE after shift in
hexadecimal
2147483646 after shift in decimal
To the top

Q. What does negative shift distance means?


A:
Actually, the rule is the same, the shift distance will be masked no matter it is positive or
negative. For integer the mask is 0x1F or 11111, in other words, take the lowest 5 bits.
For long, the mask is 0x3F or 111111, in other words, take the lowest 6 bits. 34555 >> 65
34555 >> (65 & 0x1F)
34555 >> 1
17277 -8 >> 2
-8 >> (2 & 0x1F)
-8 >> 2
-2 -8 >> -2
-8 >> (-2 & 0x1F)
-8 >> 30
-1
To the top

Q. How to convert byte[0]=2 byte[1]=1 to its corresponding short value?


A:

• You are not allowed using byte as your array name, since it is a reserved word.
Let's change it to b[]
• It depends that you use "Intel" order (with low byte first) or opposite.
• If we choose to use the regular order (with high byte first), the answer is
short s = (short)(((b[1] &mp; 0xFF) << 8) + (b[0] & 0xFF));

To the top

Q. When do we need to use shift operator? Can you give some example?
A: Some of these examples are from Mr. Bill Brogdon, Thanks, Bill.
1) Optimize integer multiplication/division.
3678348 * 2
3678348 << 1
------------------
3678348 / 2
3678348 >> 1
are the same, but shift is much more efficient.2) Use bitset to handle bunch of boolean
variable arrays, save huge amount of memory. 3) Assembling int values from byte
streams, especially byte streams created in "Intel" order with low byte first. (And of
course, the opposite function of writing Intel order from Java.) 4) Packing a large number
of variables into a single int or long. For example, if you have a variable that can only
range from 0 to 15 you can pack 8 of them into a single 32 bit int. 5) Grabbing red green
blue color and transparency data out of a pixel.
To the top

Math class and math related

To the top
Q. How to convert degrees to radians?
A:
This is a math question, not a Java question. However, the Math.cos(), Math.sin() only
accept double in radians. If you enter degrees, it will compile/run OK, but give you
wrong results.Just remember 2 PIs is equivalent to 360 degrees. Simple double degrees =
60;
double rediants = degrees * 2 * Math.PI / 360;
To the top

Q. Why Math.abs(Integer.MIN_VALUE)) return a negative value?


A:
Overflow, since integer range is -2147483648 to 2147483647.
Actually this is a real interesting one for learning 2's complement system. Everyone
knows the range of bye is -128 to 127, if you use Math.abs(-128) and than cast it back to
byte, you will get the similar result. Here is a program with output to help you understand
the question.
public class Abs {
public static void main (String args[]) {
System.out.println(Math.abs(Integer.MIN_VALUE)); //-2147483648
System.out.println(Math.abs(Integer.MIN_VALUE+1)); //2147483647
System.out.println((byte)Math.abs(-128)); //-128
System.out.println((byte)Math.abs(-127)); //127
}
}
To the top

Q. Why float f = 1/3; does not need a cast, and no compile-time error?
A:
1/3 results 0, which is a int.
You need to understand that operator '/' is overloaded. If both operands are int, it is a
"div" in Pascal term . 1%3 results 1, 1 mod 3 results 1, in Pascal term. If you don't
know Pascal, just think about 2nd grade math. Remember, second grader does not know
anything about decimals. 7 divide by 3, the quotient is 2, and remainder is 1. 7/3 results 2
7%3 results 1 because they are integer operations. If we change the statement to
float f = 1.0/3;
you will get a compile time error, since it is a double division as you expected.Integer
division has its real meaning in the real physical world. For an example question, "10
children need to be formed 3 equal size play groups, how do you divide them?" I believe
you will never say, "put 3.3333... children into each group." but "put 3 of them into each
group, left one. They may play in turns." There is no decimal part here!!! Not
everything is divisible. Don't you agree?
To the top

Q. Why int i = 2147483647 + 1; is ok, but byte b = 127 + 1; is not compilable?


A:
Range of int: -2147483648 to 2147483647 Range of byte: -128 to 127It does look
conflict at the first glance. However, it is correct. int + int is supposed to be int. That is
why the first assignment is ok, even it overflows to a negative int. Note: 2147483647 + 1
results -2147483648, not 2147483648 H because they are integer operations. owever,
127 + 1 results 128, which is an int operation too. The result is out of range of byte.
Compile time error!!!

Q. Why Math.abs(Integer.MIN_VALUE) give me a negative number? How about


float?
A:
int range is (-2^31) - (2^31-1) Positive int exceeds that will overflow to the negative
territory.How about float? Run the following program to see what JVM tells you:
public class A {
public static void main (String [] args) {
System.out.println("Integer.MAX_VALUE = " + Integer.MAX_VALUE);
System.out.println("Integer.MIN_VALUE = " + Integer.MIN_VALUE);
System.out.println("Float.MAX_VALUE = " + Float.MAX_VALUE);
System.out.println("Float.MIN_VALUE = " + Float.MIN_VALUE);
System.out.println("Math.abs(Integer.MIN_VALUE) = " +
Math.abs(Integer.MIN_VALUE));
System.out.println("Math.abs(Float.MIN_VALUE) = " +
Math.abs(Float.MIN_VALUE));
}
}

/*
output
Integer.MAX_VALUE = 2147483647
Integer.MIN_VALUE = -2147483648
Float.MAX_VALUE = 3.4028235E38
Float.MIN_VALUE = 1.4E-45
Math.abs(Integer.MIN_VALUE) = -2147483648
Math.abs(Float.MIN_VALUE) = 1.4E-45
*/
To the top

Q. When I do floating-point operation, why some unwanted result comes out?


// Example, why the red extra comes out?
double x = 27.475;
double y = 7.22;
System.out.println(x - y); // 20.255000000000003
A:
That is a famous floating-point phenomenon. Your number is represented in decimal, and
your computer represents them in binary, some discrepancy will happen with that
conversion back-and-forth. It is normal since Machine Language / Assembly / Fortran
time. If you go to an interview, someone ask you this question, you don't know the
answer, and inexperienced programmer situation will be exposed to the interviewer
immediately.

When you output, format it to what you desired.How the precision changed? This is no
easy job.

You need understand what is radix.


Radix for decimal is 10
Radix for binary is 2 29.3 in decimal is actually

2 * 101 + 9 * 100 + 3 * 10-1 In binary


11101.010011001.............

Do the same thing, but replace 10 to 2. However, the number will never end. You will
find out something is short in decimal may become infinite long in binary. And the
opposite will not be infinite long, but possible longer then the computer system allowed.

Computer cannot allow infinite long number, it must be truncated to fit the precision of
the floating-point number in the system. Therefore, the value of some floating-point
number changes in the conversion from one radix to another radix back-and-forth.

If 29.125 in decimal is converted to binary, there are no problems. It will be 11101.001 in


binary precisely, since 0.125 is 2-3 or 1/8

This is mostly math in computing problem. Real numbers in math are continuous.
However, real numbers in computer must be discrete. Therefor, we don't call them real
numbers, but float and double.

Theoretically, this kind unwanted results are inavoidable, no matter how accurate your
computer is or will be in the future. You'd better understand it. Thanks!

To the top

Q. How to convert floating point decimal to binary?


A: The followings might give you some hint!
In the integer part, you devide by 2. In the decimal part, you multiply by 2
Decimal Binary
2 10
4 100
8 1000
16 10000
0.5 0.1
0.25 0.01
0.125 0.001
0.0625 0.0001
...

You should get my point now.

To the top

Q. Why boolean x = 999999.99f == 1000000.00f; is true?


A: Misleading, isn't it? I give you some more here
public class A {
public static void main(String[] args) {
// some misleading examples here!
System.out.println(999999.99f == 1000000.00f); // true
System.out.println(999999.99999999999 == 1000000.00000000000);
//true

// don't be misleaded by the above big 9's


// The numbers don't need to be real long and many 9's
System.out.println(27.475 - 7.220 == 20.255 ); // false
}
}
A rule of thumb:
Never compare two floating-point numbers (double or some future "double double"
included) with == or equals or = or EQ or eq. or whatever notation for equality in the
specific programming languages (Machine Languages, assembly, Fortran, LISP, Pascal,
c, VB, c++, Java, c#, ...), even it works sometimes. The results are mostly unpredictable
or misleading.

That is a computer science ABC, I'm sorry to say it. I wish you are not offended.

Read here for the reasons from above QA:Q. When I do floating-point operation, why
some unwanted result comes out? even the question sounds a little different to the
topic. However, the reason is exact the same.

How do I obtain floating-point number equality, if I really need the result?


Classroom and real life solution:
if (abs(d1 - d2) < 0.000001 * min(abs(d1), abs(d2)) )
{
bequal = true;
}
0.000001 can be replaced by any relative precision, which satisfies you or your business
needs. This provided a practical way for equality checking of floating-point numbers in
computer world and real world. The answer obtained is not misleading, but more accurate
to the problem you want to solve.
To the top

Q. Why (Double.NaN != Double.NaN)?


A: Since it is defined this way.
Yes, Expression (Double.NaN != Double.NaN) will return true, and (Double.NaN ==
Double.NaN) will return false.

See JLS 4.2.3


NaN is unordered, so the numerical comparison operators <, <=, >, and >= return false if
either or both operands are NaN (?5.19.1). The equality operator == returns false if either
operand is NaN, and the inequality operator != returns true if either operand is NaN
(?5.20.1). In particular, x!=x is true if and only if x is NaN, and (x<y) == !(x>=y) will be
false if x or y is NaN.

To the top

Q. Can we use one dimension array to represent higher dimension array?


A:
The only thing you need to do is a math formula. A one dimension array can be a two
dimension M*N matrix, as long as you know M and N, as well as how to map (i, j) to
index, or map from index to (i, j)

For the above


index = M * j + i;

Of course, you need validity checking too, I think you know what I mean here. You
can make N open, but M has to be fixed for 2-dimension array. Generalize a little, the last
dimension can be open, M*N*...*X*Y*Z, anything before Z must be known before hand.
Z can be open.

To the top

Q. An interesting math quiz. Put n different balls into m boxes, at least k balls in
each box. How many ways can we put them?
A: Hints:
if (n < m*k)
return 0;

if (n == m*k)
return n!/(m! * (k!)^m); //pseudo code, not Java

// Code written by you!


// WARNING: It is not as easy as it looks...

To the top

Q. How math round() works? Why so many discrepencies?


Java: Math.round(-8.5) result: -8

but:
Excel:Round(-8.5, 0) result: -9
SQLServer:select round(-8.5, 0) result: -9
Oracle:select round(-8.5) from dual result: -9
A: round() method definition in math is a complicated issue.
Be very careful to explain how round works. There are 5 different ways defined for mid
point round!

Java Math.round() chooses the way called "towards positive infinity" The followings
choosed "away from zero":

Excel:Round(-8.5, 0) result: -9
SQLServer:select round(-8.5, 0) result: -9
Oracle:select round(-8.5) from dual result: -9
There are 3 more ways...

• "to even"
• "towards negative infinity"
• "towards zero"

The contents are according to IEEE754.. They are all correct as long as it works
consistently!!!!

How toEven works?

2.5 --> 2
3.5 --> 4
Is it inaccurate? Yes, that is the purpose of round() function. You want it accurate, then
don't use round.
To the top

Q. How to generate random number in a range?


A: Simple
int getRandom(int min, int max) {
return min + (int)(Math.random() * (max - min + 1));
}

To the top

Expression & Java operators

Q. What is the differences between == operator and equals() method?


A:

1. No equals() method for primitive types. Of course, primitive type wrapper classes
(e.g. Integer class) do.
2. == operator compares the values of primitive types.
3. == operator compares the reference (values) of Objects.
4. Unlike C++, Java does not allow operator overwriting. Which means two
identical objects A and B, A==B will never happen.
5. Object.equals() will behave exact the same as ==, unless it is overridden by the
subclass.
6. More equals / == examples here, TestEqual.java
7. Warning: Don't try this at work!

To the top

Q. What is the difference of --b and - - b? Why does the following code behave
strangely?
byte b = 2;

b = -- b; //Compiles ok and prints 1


b = - - b ; //Compiler error because explicit cast needed to convert
int to byte.
A:

1. Spaces are significant here. No spaces allowed in the follow operators: --, ++, +=,
-=, /=, *=, %=, etc.
2. -- is decrement operator, in -- b or --b, the operand keeps its original type. It is
byte in your case.
3. - - b is equivalent to -(-b), like most integer type operators, it is default to int.
4. Assign an int to byte; type cast is required.

To the top

Q. What is the difference of x=x+3 and x+=3? Why one needs type cast and the
other does not?
char x = 'a';
x += 3; // ok
x = x + 3; // compile time error
A:
Because x += 3; is equivalent to x = (char)(x+3); while x + 3 is default to int operation,
assign an int to char must cast.Copied from JLS 15.26.2 "A compound assignment
expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is
the type of E1, except that E1 is evaluated only once. Note that the implied cast to
type T may be either an identity conversion (?.1.1) or a narrowing primitive
conversion (?.1.3)."
To the top

Q. What is expression in Java or other computer languages?


A: Expression must have a value! It can be assigned to a variable with corresponding
type.
Expression examples: (3 + 4)
int expression with value of 7.
int x = (3 + 4); //OK (1 != 2)
boolean expression with value of true.
boolean b = (1 != 2); //OK ("girl")
String expression with value of "girl".
String s = ("girl"); //OK(math.max(2.3, 4.9))
double expression with value of 4.9.
double d = (math.max(2.3, 4.9));//OK(if (x > y){ return x;} else {return y;})
Invalid expression with no value! It is because if-statement does not return any value.
Can you assign it to anything? NONE!!
To the top

Q. What is logical operator short-circuiting?


A:
This is a basic concept in computer sciences, not limited to Java. You'd better understand
it.Two boolean expressions A, B, if A is false, you know A and B must be false, you
don't need to evaluate B to know the answer.If the computer language allows and operator
short-circuiting, B will not be evaluated. If B happens to be a long and complicated
calculation, and produces a lot of side effects, even throw exceptions, those will not
happen when A evaluates false.However, if the computer language does not allow and
operator short-circuiting, B will be always evaluated, no matter what is the value of A.c
language is always short-circuiting. Standard Pascal does not allow short-circuiting.
However, Turbo Pascal does.Java just tries to make your life more miserable, it makes
&& short-circuiting, but & not short-circuiting.I used && and & to illustrate the
concepts, you need to figure out how || or | works in Java. This is your homework
assignment. In addition, you need to know:

• In Java, | & are overloaded, they are bitwise operators as well as non-short-
circuiting logic operators, which depends on the parameters passed to them.
Operator overloading is not new, it is used since FORTRAN time.
• Here is the full compilable, runnable, testable code for you to play with.

public class ShortCircuiting {


public static boolean bfunction()
{
System.out.println("***Inside bfunction, " +
"we have a side effect!***");
return true;
}
public static void main(String[] args) {
System.out.println("=======================");
if (false && bfunction()) {
System.out.println("This will never be printed out");
}
else {
System.out.println("&& logic operator used, " +
"you will not see the side effect.");
}
System.out.println("=======================");
if (false & bfunction()) {
System.out.println("This will never be printed out");
}
else {
System.out.println("& logic operator used, " +
"you see the above side effect.");
}
System.out.println("=======================");
System.out.println("You should understand the " +
"concepts of short-circuiting and side
effect.");
System.out.println("Now, it is your turn to try the || or |.");
System.out.println("=======================");
}
}
//output:
//=======================
//&& logic operator used, you will not see the side effect.
//=======================
//***Inside bfunction, we have a side effect!***
//& logic operator used, you see the above side effect.
//=======================
//You should understand the concepts of short-circuiting and side
effect.
//Now, it is your turn to try the || or |.
//=======================
To the top

Q. When (1) x and y refer to two different object, or (2) x.equals(y) returns false, is
(x.hashCode() == y.hashCode()) always return false in these two situation. Why?
A:
No, not necessarily. The opposite is true. When (3) x and y refer to the same object, or (4)
x.equals(y) returns true, then (x.hashCode() == y.hashCode()) always returns true.Read
JDK DOC here, it helps for sure!
http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode()
To the top

Arrays in Java

Q. What are arrays in Java? Do all array elements be initialized to default value?
A:
Arrays are objects in Java. Array elements are just member variables of the class, and
they are initialized to default value as any other class of objects.MyObject[]
myobjarray; There is no array here, only an array reference type variable called
myobjarray. If it is a field in another class, myobjarray will be initialized to null. If it is in
a method, it will not be initialised. No exceptions here!!! MyObject[] myobjarray =
new MyObject[5]; You are initializing myobjarray by constructing a MyObject[5] array,
inside the new object instance of the MyObject[5] array, all fields will be initialized to
default values, which are myobjarray[0] = null, myobjarray[1] = null, ... and the length
field would be initialized to 5. No exceptions here either!!!The only difference is that
array classes do not have an known name. If you are really interested to know the class
name of various arrays, you can see them here. It actually prints out some odd class
names of arrays: TestRange.javaSee the bottom of the code.
To the top

Q. How to create an array with actually 3 HashMaps in it?


A: See the following code snippets
HashMap[] maps = new HashMap[3];
for (int i=0; i<3; i++) {
maps[i] = new HashMap();
}

//or

HashMap[] maps = new HashMap[]{new HashMap(), new HashMap(), new


HashMap()};
To the top

Q. How to display elements of an Object array?


A:
Concepturally, when you want to print/display something, what you need to do is
overring the toString() method of your object. Then you can print it like:

System.out.println(myobj);
If it is an array, add a loop. If it is in an ArrayList, you even can do something like this:

System.out.println(myobjarraylist);
Try it, seeing is believing.
To the top

Q. How to define arrays in Java, C/C++, and C#? Are they different?
A:
In c/c++, very confusing!!

// float[] only applies to the first variable of the right variable


list.
float[] f1d_a, f1, f1d_b[];

// is equivalent to
float f1d_a[]; // or float[] f1d_a;
float f1; // f1 is not an array
float f1d_b[]; // or float[] f1d_b;
In Java, better, but still confusing!!

// float[] applies to all variable of the right variable list.


float[] f1d_a, f1d_b, f2d_a[];

// is equivalent to
float f1d_a[]; // or float[] f1d_a;
float f2d_a[][]; // or float[][] f2d_a;
float f1d_b[]; // or float[] f1d_b;
In c#, it is not confusing unless you think in other language way.

// float[] applies to all variable of the right variable list.


// but float f2d[][] is not allowed

float[] f1d_a, f1d_b;


// is equivalent to
float[] f1d_a;
float[] f1d_b;

// float f1d_c[]; error!!!


Disclaimer: Not paid by Mr. Bill Gates.
To the top

Class Object

Q. System.out.println(MyClass.class); What is .class here? Is it a field of MyClass?


A: No, class is a Java keyword, it cannot be used as a field. Then what is it?
See the following code
public class MyClass{
public static void main(String[] s) {
MyClass m = new MyClass();
System.out.println(MyClass.class); // class MyClass
System.out.println(m.getClass()); // class MyClass
}
}
I did a search in JDK source code. No class as a field anywhere, not in Class class, not in
Object class, absolutely nowhere. It is the keyword class can be used this way, to return
the Class instance object of MyClass.See details in JLS.

Q. All Java classes are instances of class Class, can you give an example?
A: Yes, see the code bellow.
It just tells you class A and class java.lang.System is an instanceof Class.
//*******************************
public class A {
public static void main(String[] args) {
boolean b;

b = A.class instanceof Class;


System.out.println(b); //true
System.out.println(A.class); //class A

b = System.class instanceof Class;


System.out.println(b); //true
System.out.println(System.class); //class java.lang.System

// Interesting enough, Class.class is also an instance of Class


b = Class.class instanceof Class;
System.out.println(b); //true
System.out.println(Class.class); //class java.lang.Class
}
}
//*******************************
To the top
Coding style

Q. Why use i as an array name is a bad idea?


A: No surprises is an important principle in good programming practice.

1. Please do not use i, k as array names. They are default to be used as integer
variable names since Fortran time. Fortran is still alive today, even it is the first
high level language in computer history, and we do inherit our history. It is easy
to confuse other programmers.
2. Use int[] myarray instead of int myarray[]. This has been controvertial since C
time. However, int[] looks more a type, a lot of industry coding standards have
the same suggestion too. In addition, C# made this official now.

To the top

Q. What is the difference of String[] myString and String myString[]?


A: They are the same in Java or C++.
String myString[] is illegal In C#, a great overdue improvement!!!
However, String[] myString is generally considered to be better. String myString[] is
illegal In C#, a great overdue improvement!
String yourString[]; // not compilable in C#, but it is OK in
C++/Java
String[] myString; // compilable in C#, C++ and Java, since it is
better and clearer!
To the top

Comparing Java with C++

Q. What is the difference of null in Java and NULL in C++?


A:
null in Java cannot be a primitive value, it is for reference only. 0 in Java can only be a
number, and it cannot be an object reference.char c = null;
String s = 0;
The above 2 are not even compilable in Java! char c = NULL;
Object* p = 0;
They will be OK in c/c++. Java is a more strong-typed and safer language than C/C++.
Thinking in Java now!
To the top

Q. How to define struct in Java?


A: Use class instead. There is no keyword struct in Java.

• If you don't need methods, then don't define them. If you want all attributes/fields
public like in C, then so define them.
• In C++, struct is just the same as class, except all members are default to public.
• struct in C is just equivalent to class without methods/functions, since C is not OO
yet.

To the top

Q. What does virtual keyword mean in C++? Do we have equivalent in Java?


A: virtual in C++ indicate function must be dynamically bound, or binding at runtime.

• C++ is default to static binding, if virtual, than dynamic binding apply.


• Java is default to dynamic binding, unless you specify the method as static.
• Therefore, we need to be careful, when we talk function/method
overloading/overriding. Make sure we are not compare oreange with apple.

To the top

Q. Why c++ is not platform independent?


A:
C++ compiles to binary code (.obj, .exe, .dll, a.out etc.). Binary code (Machine code, 0's
and 1's) are machine dependent.Java compiles to byte code which is independent of any
machine. It need to be interpreted to binary code by JVM, and executed by the machine.
To the top

Q. Why can't we declare a static variable in a member function of a class in Java


like in c++?
A:
Simple answer: That is Java creator's decision
A little Guess work by me: Java want that static means per-class, like class-method,
class variable, are static. Per-method or per-file like c++ is not consistent with this kind
of thinking, and not OO. Don't forget C++ is a hybrid language (OO/not OO).
To the top

Q. What kind of variables put onto calling stack, what on the heap in c++ and Java?
A:
In Java, object cannot put on calling stack. Only primitive types local variable and local
references to Objects can be put onto stack. All objects are on the heap.This is different to
C++. In C++, local objects can be put onto calling stacks. Object can be automatic
variables.
// In c++
Object o; //real object on calling stack
//when method call completed, it is popped
out, gone
Object *p = new Object(); //real object on heap
//explicit deletion required to avoid mem-
leak
// In Java
Object o; // no object, only a reference on calling
stack
Object o = new Object(); //real object on heap
//when it is no longer referenced, it will be
GCed.

I heard somebody was doing research on this, and experimenting to put objects onto
calling stack to improve the efficiency of Java. However, it seems never becoming
reality.

To the top

Q. What is Enumeration? What is enum keyword?


A:

Enumeration is a Java interface. but you'd better use Iterator instead, in new code.enum
C/C++ keyword for define an enumerated type for better type checking, very useful in
coding practice. No counter part in Java. A friend of mine tried to reinvent it in Java, but
found too much pain to do it.Exampleenum CarSize {
subcompact,
compact,
fullsize,
minivan,
pickup,
suburban,
limo
};They are actually numbers (0..6) in the above example. You use them like constant, but
with type checking and better code readability. You can define them in a class too.
To the top

Q. Is reference in Java the same as C pointer?


A: They are basically the same, a space can hold other's address. However pointer in
C/C++ is much more powerful than reference in Java.

• In Java, we call it reference, which holds the address of an Java Object. You
cannot dereference it in Java. You cannot do arithmetic on it in Java.
• In C/C++, we call it pointer, to hold the address of anything, include an object,
function, primitive type (int. long. char. etc.), or even another pointer. Now, you
can see, pointer in C/C++ is much more powerful than reference in Java. You
cannot dereference a ponter in C/C++, you get pointer of pointer. You can do
arithmetic on it in C/C++, which is extremely powerful, but extremely unsafe too.
Have you seen a "core dumped" error on UNIX? You are overwritting the core of
the operating system!!!!
• Why does someone say, "There is no pointer in Java."? Hehe, ask him/her. Just
take a look at java.lang.NullPointerException...

To the top

Q. What is dereferencing? Does Java allow dereferencing?


A: See definition here:
http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=dereference&action=Search No, Java
language does not allow dereferencing. See an example here, please read the
comments.
// This is in C++ language:
Object* pObj = new Object();
// equivalent to java: Object obj = new Object();
// you can see obj in Java actually is a pointer
// that is why there is a NullPointerException in Java

Object** ppObj = &pObj;


// dereferencing the Object address
// or find out where you store the Object address
// pointer of pointer in C++
// There is no Java equivalence to it.

// Java is a lot safer than C++ because of it,


// but less powerful to certain extent.
To the top

Q. Is there any mechanism which gives the byte size of a arbitrary object in Java
like sizeof() in c++?
A: No, there is none.
However, you can get not very accurate estimation by using the floowing code. But if the
class has String data members, the result will be very misleading. It can be inaccurate
when JVM changed the memory allocation for some other reasons.
Runtime rt = Runtime.getRuntime();
long before = rt.freeMemory();
Object o = new Object();
long after = rt.freeMemory();
long size = after - before;

Q. What is union in c/c++? Is there something similar in Java?


A: No. but Why?
Variant record in Pascal, Union in C. They are generally considered type unsafe in
computer languages theory. That is just the language designer's choice, safety first, or
flexibility first. Java is designed to be safety first, that is why Java does not support it.US
defence department's effort, the final winner Ada does not support it for safety reasons.
You probably can imagine why they chose not to include it, can't you? How
union/variant record works, 2 or more different type data members occupy the same
memory space, use the largest size one to allocate the memory size of
class/struct/variable record.
To the top

Q.These two pieces of code (Java/C++) are almost identical, but produce very
different results. Why?
// A.cpp
#include <stdio.h>
class A {
public:
A() {
doSomething();
}
virtual void doSomething() {
printf("doSomething in A\n");
}
};

class B : public A {
public:
virtual void doSomething() {
printf("doSomething in B\n");
}
};

void main() {
B* b = new B;
b->doSomething();
}

// output:
// doSomething in A
// doSomething in B

//------------
// A.java
public class A {
public A() {
doSomething();
}
public void doSomething() {
System.out.println("doSomething in A");
}

public static void main(String[] args) {


B b = new B();
b.doSomething();
}
}

class B extends A {
public void doSomething() {
System.out.println("doSomething in B");
}
}

// output:
// doSomething in B
// doSomething in B
A:
We all know, C++ is default to static binding, if virtual, than dynamic binding apply.
However, the doSomething() call in A constructor is not dynamically bound even it is
virtual.

Java is default to dynamic binding, unless you specify the method as static. The
doSomething() call in A constructor is dynamically bound.
The reason is C++ is using vtable to load the class, but Java is using ClassLoader to load
the class. Of course, Java could have designed to not allow dynamic binding in
constructor, since it is generally considered not good practice of OO. Try to avoid calling
overridable method in constructor. It is considerred a good coding practice in some
opinions. However, there is no universal agreement on this issue. You are most likely to
do what your archtects or boss asking you to do.

Just remember the facts will benifit you, since they are both good interview questions.
To the top

Q. There are a lot of syntax similarities between Java and C++, what are the
fundamental differences?
A:
Read some answers from the founding father of the great C++ programming language
Dr. Bjarne Stroustrup . You will be suprised how much you can learn from there!
Search the word Java. It will be great experience for you no matter you knew C++ or not.
We need pay respect to history. Even C++ is not history yet, it is still very much alive
as Java.

Q. How to define C-like global variable in Java?


A: The basic rule is not to use global variables unless absolutely necessary.
This rule applies even you are writing C or Pascal code.

When it is really really absolutely necessary(??), make a class called Global and all
members public static, no setters, no getters. Make them look very obvious unmistakenly
global. Then it is a duty of every programmer to maintain the integrity of Global class.

public class Global {


public static int g_num;
public static char[] g_charray;
public static byte[] g_bytearray;
// more here
}
Please, please don't use this technic unless absolutely necessary. Use it, don't abuse it!!!
To the top

Q. What is the difference of function and method?


A: They are basically the same thing.
subroutine, procedure, function, method, they are basically the same thing, used in
different languages, in computer science history.

• Method is usually used in OO languages, such as Java.


• Function is used in c/c++/Pascal.
• Procedure is used In Pascal, funtion returns a value, procedure does not.
• Subroutine is used in FORTRAN/BASIC.
• ... I just give you some examples, not a complete list.
What is the common use for them? Make code reusable. Subroutine is a big invention in
FORTRAN language! We don't need to write the same piece of code again and again and
again! It seems a simple commonplace to you and me. However, it was a great invention
in computer science history!
To the top

Miscellaneous

Q.When I run the code with "java test *", why it has a number of parameters as
many as the number of files under the directory?
class test{
public static void main(String args[]){
for (int i = 0; i < args.length; i++) {
System.out.println("Para"+i+":"+args[i]);
}
if (args.length <= 0) {
System.out.println("No para");
}
}
}
A:
This is a wild card in dos, "*" stands for everything fit the context under the current
directory. Have you ever tried to compile all Java files in the directory by typing "javac
*.java" or delete all files and subdirectories under the current directory by typing "del
*"? DOS is doing the same thing in all above.
To the top

Q. How to use Runtime.addShutdownHook() method? Can you give an example?


A: Read the javadoc very carefully to understand the rule.
Here is a simple example.
class Test {
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// will exec when JVM Shut Down
System.out.println("Exiting...");
}
});
// do whatever you are supposed to do
}
}
To the top

Q. How to use Comparator interface?


A: See your sample code here: SortBy.java
To the top

Q. Why the following code causes a Stack over flow error?


// Dodo.java
public class Dodo {
Dodo d = new Dodo();
Dodo() {
System.out.println("Dodo has been made");
}
public static void main(String[] args) {
System.out.println("About to make my first dodo");
Dodo d = new Dodo();
System.out.println("Will now make a Second Dodo");
Dodo d2 = new Dodo();
}
}
A:
Good stuff!! You create a Dodo as Dodo's data member, cause a recursive call without an
exit point. That is a famous No-No in computer science course. Stack Overflow is
guaranteed. No matter what language is used. See your example how to avoid this here:
02.htm#acc_Q3 If you don't understand what is recursion, then you'd better find a
programming or data structure textbook to read. It does not need to be Java, better find a
good textbook before Java. It is basically something call itself. The typical no exit
recursion in real life is looking at your image in 2 face-to-face mirrors.
To the top

Q. What is asynchronous architectures?


A:
The contrast is between a completely procedural program that starts, does its task and
quits and the more open architecture in which the program starts and waits for something
to happen that it has to respond to. synchronous example: model dialog call, the
procedure call it will not continue until the model dialog returns. asynchronous example:
modelless dialog call, you method called the creation of modelless dialog, the modelless
dialog will run in its own thread, your method will continue does its own things. This
happens the same in any programming languages, not specific to Java. Another very good
example is in Windows, SendMessage() synchronous, which sends message to the other
party, and waits for the thing to happen, then return to the caller. PostMessage()
asynchronous, which posts the message on the message queue, and return immediately.
When the other party performs the action, the caller does not care. You don't need to
know windows programming details to understand the concepts. If you know CORBA,
the oneway modifier will define an asynchronous request.
To the top

Q. Why should I never use undocumented features of software?


A:
Since it might change anytime without notice. Another one is when you switch the
vendor, you willbe in big trouble.

In our job, we used JAXP1.0 and Xalan. When we transfer to JAXP1.1, and saxon, after
necessary changes, it works great. However, one programmer's code was broken, and he
does not know why. The reason is he used some undocumented features of xalan, which
are not specified by JAXP specification. Never code anything depending on some
undocumented features!!!
Code against interface (API spec) only, please!!!
To the top

Q. Why Java does this? Why Java does that?


A:
To computer languages or natural languages, I always prefer to ask what and how
instead of why. Even though I know there are a lot of good and bad reasons behind them.
The good ones make the language vital and successful, the bad ones make future
improvement and replacement possible. Languages (natural and programming
languages included) are not rigorous science, a lot of human factors are involved. To
programming languages, another factor is the cost. This is a more philosophical and
time-efficient decision of mine. You can make yours different than mine, of course.
Sorry, it is usually not a very satisfactory answer for you.

Q. How to use global variable in Java?


A: Global variables are not recommended to use in OO programming, actually even they
are not recommended in procedural programming either.
However, if you really want to use them, you can. My trick is define a final class with
private constructor and all public static fields. Such as
public final class G {
private G() {}

public static int g1;


public static boolean g2;
public static Object g3;
//...
}
In this way, nobody can instantiate the G class, no class can derive from the G class.
Now, every field in G can be considered as global variable. If some programmer made a
mistake in G, everyone else gets hurt!!!! If you use global variables ,you have to live with
the consequence of global variables too!!!!
To the top

Q. Do I need to learn other languages?


A: If you want to be an IT professional, you do!
MY Suggestions are

1. Learn one programming language first, code as much as you can, write some real
applications
2. Learn at least one more different languages, then you will get a better feeling of
similarity and differences of them. You will definitely became a better
programmer by doing that.
3. Learn more languages when job requires you to do so.

Happy Learning!
To the top
Q. What are the differences between text and binary files?
A: Many differences.

1. Of course, in computer, everything finally is 0's and 1's. Therefore, you can say
text files are also binary.
2. The first is text files are made of text, usually has line.separaters.
3. 34893 and 23 occupy different bytes in text file, but same bytes in binary.
4. Binary files can carry more information than text files.
5. Binary file format is more close to the storage.
6. Since we have so many different types of binary files, the differences have no
end...

To the top

Q. A comment on plagiarism
A: See original discussion here.
I saw many posts on various forums with copy from other's article or post without
referring to the original. Here is my comments on that. Put it here for reusibility too.Is
it your own article or you copied it from somewhere?

• If it is a copy, you should post where you copied it from. This is a basic respect to
the author. It would be also a great help to the reader.
• If it is your own article, please say so...

We should stop plagiarism! Thanks!

To the top

S-ar putea să vă placă și