General Questions: 1. What Is Java?
General Questions: 1. What Is Java?
1. What is Java?
A:
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!
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!
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.
• 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
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.
• 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.
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
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"); }
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);
}
break lbly;
// compilable Error: statement not reached
//System.out.println("This will never be printed out.");
}
}
}
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
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. 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.
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.
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.
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:
8, 1
Boolean bit true false false
used
- +
double 64 0.0
1.79769313486231570E+308 1.79769313486231570E+308
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!
• 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
The float to long should be more obvious, since its decimal part will be lost.
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.
class A {}
class B extends 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.
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.
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.
// output: 3
// think why?
A:
Remember the following will help:
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.
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.
Java Packages
• 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;
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. 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.
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);
}
• 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.
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){
// 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);
}
}
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!!!!!!!!!!!!!!!!!!!
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);
}
}
// this is a method A
void A() {
System.out.println("We are in method: void A()");
}
// output
// We are in contructor: A(int i)
// The i value is 3
// We are in method: void A()
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);
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;
}
static {fsn=6;}
{fn =8;}
}
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
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.
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
// 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.
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.
• 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.
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.
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.
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 {
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.
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 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;
}
}
System.out.println(bb.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;
}
}
• 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
// 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. 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.
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???
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{
//...
}
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!
}
}
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
Avoid local declarations that hide declarations at higher levels. For example, do not
declare the same variable name in an inner block:
void doThat() {
System.out.println("Base instance doThat()");
}
}
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");
}
}
public class T{
public static void main(String arg[])
{
new Sub().m1();
}
}
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...
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:
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
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");
}
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
}
class Base {
private void method1() {
System.out.println("Base.method1()");
}
// run output
// Base.method3()
// Base.method1()
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
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!
}
}
class SubBase extends Base{
String s = "string in SubBase";
void init(){
System.out.println("init() call in SubBase");
}
}
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?
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);
}
}
// output
/*
In SubBase, x = 2
In Main, the (?) x = 3
*/
A: Danger: Do not try this at work!
• 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.
• 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.
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.
// not compilable
//transient class MyInner8 {}
}
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.*;
add(btn);
}
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 .
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. 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}
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:
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.
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);
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 = "[\\|]+";
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.
void setRunFlagFalse() {
runflag = false;
}
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();
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);
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);
}
}
}
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.
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. ");
}
}
Nothing changes by assigning your Thread a name. It only gives you the convenience of
debug, since it has a name you know.
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.");
}
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);
}
}
}
}
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. ");
}
}
How can we solve the problem? There are two ways to do it.
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.
How to avoid/correct them? Find out what causes your thread starvation, and correct
them.
• 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.
Serialization
• 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
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
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
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();
}
}
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.
To the top
This is because the entire byte array is in memory; there is no circumstance in which an
IOException is possible.
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);
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
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.
Garbage Collection
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".
// 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
a = null;
b = null;
// a and b are both eligible for GC now
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;
}
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
It is vender and platform dependent that when and in what order the eligible for
GC objects will be GCed.
The object is no longer referenced or referenced only by objects, which are eligible
for GC.
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();
}
}
csObj = null;
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
See an example below, pay attention to the comments and commented out code.
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
}
}
To the top
To the top
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.
For example: NullPointerException can happen anywhere as long as you have an Object
o, and code like
o.doSomething();
o.someField = somthing;
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?
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
arr[0]="hello";
arr[1]="hi";
tmp = s1;
s1 = s2;
s2 = tmp;
}
tmp = arr[ix1];
arr[ix1] = arr[ix2];
arr[ix2] = tmp;
}
}
To the top
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.
Pass by Value
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. 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
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)
int y = 5;
int y = y++ + y++; //(the y value will be 11)
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
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) {
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;
// not compilable
// byte byteResult = byteNum >>> byteDist;
• 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] ∓ 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
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 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
/*
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
When you output, format it to what you desired.How the precision changed? This is no
easy job.
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.
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
To the top
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.
To the top
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
To the top
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!!!!
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
To the top
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;
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
• 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.
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
//or
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!!
// 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!!
// 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.
Class Object
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;
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
•
• 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
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
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
• 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. 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.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");
}
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.
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.
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
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
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