(1),
(1b),
(2),
(3),
(4),
(5),
(5b),
(6),
(7),
(8),
(9),
(10),
advanced,
xml,
ant,
job tips,
c/c++/stl,
Algorithm,
Ruby
The questions and answers here are my selective postings on
JCHQJavaRanch,
ChinaJavaWorld and others.
After answering questions for a while, I realized that a lot of similar
questions are being asked again and again. This is because different people are in their different preparation stages of their SCJP test, and new people are
joining in every day.
The purpose is to let people in the future have a place to look for
answers. People don't need to answer the same question again and again. I'm not
intending to cover everything in SCJP test, go back to
JCHQ for that purposes. In general,
the FAQs here are harder, but not always.
Software reusability is extremely important. OO analysis, design, and
programming are invented for this purposes. So does the component-based
software. Design patterns are discovered for reusing other's design ideas. This
page is created for reusing my own answers. Hopefully, this page will make your
learning process a little easier. We all work together to make a difference!
Table of Contents |
|
|
SCJP topics covered- General questions
- Language fundamentals
- Primitive types in Java, type casting
- Java Objects
- Java Packages
- Java Constructors
- Access modifiers, etc.
- String and StringBuffer
- Methods overloading, overriding
- Basic OO concepts
- Inheritance, polymorphism, static/dynamic
Binding
- Abstract classes/interfaces
- Inner, local, anonymous classes
- Collections classes
- Other Util Classes
- Regular expressions
- Multi threading
- Serialization
- I/O Streams, Reader/Writer
- Garbage collection
- Exception handling
- Pass by value, etc
- Some Java utilities, tools
- Java left-to-right evaluation rule
- Bitshift, binary operators
- Math class and math related
- Expression & Java operators
- Arrays in Java
- Class object
- Coding style
- Comparing Java with C++
- Miscellaneous
- Faq about the FAQ
| |
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
// }
}
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.
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);
}
}
}
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();
}
Q. Is finally always been
called? Do you have a good example?
A: Yes.
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.
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
}
}
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.
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.

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
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;
}
}
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? 
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.
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...

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.
Some Java utilities, tools
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.
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!!!
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.
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.
Q. Can you recommend a Java decompiler?
A: jad is the best I know off.
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
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!
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!!