SCJP Questions & Answers by Roseanne Zhang (7)

(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

Exception Handling

Pass by Value, etc

Some Java utilities, tools

Java Left-to-right rule of evaluation

SCJP topics covered


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!!
To the top

last updated: 01-19-2009
Copyright © 1999 - 2008 Roseanne Zhang, All Rights Reserved
[JavaChina]