Java%20Questions
Short Description
Download Java%20Questions...
Description
General Questions 1. What is Java? A: • • •
Java is a beautiful island in Indonesia. Java is another name for coffee, since coffee produced in Java, Indonesia is good! Java is also a programming language was invented by Sun's programmers when they drank too much coffee. The language was called Oak, but it had a trademark conflict, then they renamed it as Jav
2. Is Java a pure OO language? A: No, it is not. neither are C++/C#/etc. SmallTalk is general considered as a pure OO language. In SmallTalk, everything is an object, including int or even + sign. Java is one step more close to SmallTalk than C++, but it is still not pure OO language. Why bother to discuss this? Language is just a tool to get the job done. Choose one is better for your job/business. If speed is absolutely critical to your application, use FORTRAN, c or assembly. Burn your algorithm into the semiconductor chips would be a good choice too, of course, if it is necessary! In some cases, OO is an obstacle. SmallTalk never becomes a main stream programming language since it is too slow. 3. In what order should we get certified, Programmer, Developer, and Architect? A: Passing programmer's test will get you an interview, since others will consider you know Java at least as a walking Java compiler, maybe more, like Tony. Passing developer's test will prove that you can code in Java, if you are not programming Java on your job yet. That is second to the real world job experience (psuedo-real-world, I like the word!). If you don't have any real coding experience in Java, or do not have any programming experience even in other languages, skip the developer's exam, and go ahead to do the Architect test? I'll consider that is crazy!!! If you are already coding in Java, go ahead to prepare for the architect exam. That may be a reasonable choice. However, SCEA is not trivial either (3 parts test). SCJP is not a prerequisite of SCEA. Why a lot of people skipped the developer exam to go SCJA (the old one), since the old one was just like SCJP, multi-choices only. If you did enough mocking exams, it was relatively easy to pass. There was another factor that almost everyone got the same test. Enough leaking made it even easier. That might be one of the reasons why Sun changed the test to SCEA.
We have SCJD Study Group. If you pass the SCJP, you are welcome to join us! 4. How do I statr to learn programming? A: Except reading, coding, Coding, CODING! • • • •
Type! Do not copy/paste examples from the book! Modify! Let the example from book do different things! Write! Write something similar, but from scatch! Develop! Develop a new application.
Q. What software or books I should buy to prepare the test? A: My suggestion, don't buy any exam software. They don't help much IMHO. But at least by one book, Bill Brogden's Exam Prep or Exam Cram will be my first choice. (Bill did not pay me anything, BTW. Get Bruise Eckle's free book, "Thinking In Java". If you can afford it, buy it. He did not pay me either. Learn how to use Sun's "The Java Tutorial" on Line, please! I saw so many questions asked here, which could be answered more precisely by a simple search of the free book from Sun. Do free mocking exams or not free ones, when you get something wrong, read, code, test back and forth until you thoroughly understand. You are not only preparing yourself for the test, but also for your future interview and job. Read, Code, code, code, and test until the Java concepts become yours. Post a question somewhere to get answer from others when you really get stuck! Free Java Books Q. What to do when we see something ambiguous on the real test? A: If you think something on the test is ambiguous, mark the question; make the best guess you can, finish the rest of the test. If you have time, go back to that question. It may not be ambiguous anymore, and then choose the correct answer. Otherwise, keep your figure crossed! Do remember MARK any question in doubt. I lost some points since I did not mark, then could not find that question to which I gave wrong answer any more. But, who cares now?
Q. What do I need watch out for filling blank questions? A: Read questions very carefully; don't jump into conclusions. ONLY write exactly what is asked for - no extra punctuation such as quotes. Some questions will give a list of words you can pick from. Don't add legs when you drawing a snake! Q. Where can I get all the Sun's test information? A: • • • •
General: http://suned.sun.com/USA/certification/javamain.html SCJP: http://suned.sun.com/USA/certification/progdetails.html SCJD: http://suned.sun.com/USA/certification/devdetails.html SCJEA: http://suned.sun.com/USA/certification/archdetails.html
Q. Do I have a future if I learn Java by myself? A: 1. I don't know how many of us learned Java not from ??. I guess, most of us are from ??. At least, I learned C++, VB, VC++, Java, Perl, Shell Script, XML, XSLT, etc. etc. from ??. Even I've taught others Java, C, Pascal. 2. Do I have a future if I learn Java by myself? I think this is a $64k question and the answer depends on you! o What is your definition and expectation of having a future. o How many effort do you want to put in for your future. o Some other factors, such as your personality, your learning style, your luck, etc..... Nobody can tell you what to do to get your ??, but you!! yourself!!!!
Language Fundamentals Q. What are Java key words and reserved words? What are the differences? A: Key words are reserved words. but not vice versa. See Java Language Keywords for details. Q. What are Java key words this?
A: this is a keyword used in Java/C++ code to refer the current instance object itself. Q. What is reference in Java? Is is the same as pointer in C/C++? A: In Java, reference is a typed named memory space which holds addrees of an Object of that type. It is called reference in Java, but called pointer in C/C++. The key differences between C/C++ with Java on pointer/reference are: • • • • • • •
You cannot put your hands on an Object without through its reference in Java. In C/C++, you can. In C/C++, you can do arithmetic on pointers, but you cannot do arithmetic on references in Java. In C/C++, you can dereference a pointer, you cannot dereference a reference in Java. In Java, all object are put on the heap only. In C/C++, you can put an Objecty/struct onto the stack. In C/C++, you can cast pointer to an totally defferent type without compiler errors. In Java, you cannot, Java is more strong typed language. In C/C++, pointer can point to primitive types too. In Java, reference cannot reference a primitive type, unlees the wrapper class is used. In C/C++, pointer can point to another pointer, in Java, reference cannot reference another reference.
Java is safer, C/C++ is more powerful. Q. What modifiers should be used for main method? Why could I violate the rule, and it still works? A: The official modifiers and signature for main method is public static void main(String[] args){}
You should remember it, and use this for your SCJP test. However, if you miss public or even use private instead, some JVM might let you launch your Java application without complaining or error messages. Why? Because some JVMs just make themselves more tolerant then they should be. This kind of practice is very common in Microsoft world. I guess Sun learned something from there. Take a look at stock price movements of both co. on 2001, you will probably understand why. • What will happen if I omit static modifier for main method? Should I do that?
Q. What will happen if I omit static modifier for main method? Should I do that? A: The code will compile, but not functional as you wanted (if you want something normal, of course). The main() method is supposed to be the entrance of the entire application. However, if you omit static, it is just another instance method, happen to be called main. It will not work as you expected. It will make yourself and your coworker confused. also make yourself confused. It will become maintenance hazard. Something is legal does not mean it is recommanded!!!!!! Don't trouble troubles until trouble troubles you!!!!
Q. How does Java compiler resolve the ambiguity to decide which methods to call? A: In the following example, four test() methods, if we pass ambiguous \b{null} to the test, which one should (will) be called? The 3 on top has super/subclass/sub-subclass relationship. The most specific one (down hierarchy) will be called. The 4th with String as a parameter, but it is a sibling of Tester. Ambiguity compile time error results. class Tester { void test(Object s) { System.out.println ("Object version"); } void test(Tester s) { System.out.println ("Tester version"); } void test(SubTester s) { System.out.println ("SubTester version"); } // Not compilable any more if you uncomment the line // since String and Tester are siblings // void test(String s) { System.out.println ("String version"); } public static void main (String args[]) { Tester c = new Tester (); // Ambiguous, the most specific one which fit will be call c.test (null); // SubTester version c.test (new Object()); // Object version } } class SubTester extends Tester{ }
"The informal intuition is that one method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error." Quotation from JLS2 Q. Where can I put labels in Java? A: See the example here. The comments and commented code tells you everything. public class Test { // lbla: //compilable Error: identifier expected public static void main(String[] args) { // lblb: //compilable Error: A declaration cannot be labeled Object o = new Object();
int
n = 1;
lblc: if (o instanceof Object) { while (true) { n++; if (n > 5) break lblc; System.out.println(n); } } System.out.println("Finished n"); lblx: for (int i = 3; i < 7; i++){ // skip number 5 if (i==5) continue lblx; System.out.println(i); } lbly: // legal before another lable lblz: { System.out.println("Watch:"); break lbly; // compilable Error: statement not reached //System.out.println("This will never be printed out."); } } }
Q. What is the return type of constructor, if any? A: General answer is constructor has no return type. Quote from Java 2 : The Complete Reference by Patrick Naughton, Herbert Schildt, Herb Schildt Pg. 147: Constructors look a little strange because they have no return type, not even void. This is because the implicit return type of a class' constructor is the class type itself It makes sense. Just think of this: MyObj o = new MyObj(); Q. What are the differences between arguments and parameters? A: In method call point of view, they are the same. The two words used alternatively for historical reasons. The same reason for so many alternatives for method, such as function,
procedure, sub, subroutine, ... If you use those words in different context, then that is a different question, I need to find my English dictionary first... Q. Is null the same as void in Java? Can I return null in a void return type method? A: No! Another No! void means return nothing. null in Java means it is a reference type, but refers nothing. null and void are very different things. For further interest, read here. Q. What is the difference of null in Java and NULL in C++? Q. Can we put a continue in a switch-case statement? A: Answer is a hesitated YES, since it can happen in a special case. // Guess the print out, then run it. // A good IQ test public class A { public static void main(String args[]) { int x = 0; while (x < 10) { System.out.print(" " + x); switch (x) { case 5: x += 2; continue; case 2: break; case 7: break; default: x++; }; x++; } } }
Q. How to compile 2 Java files simultaneously? The two inter-dependent files are sitting on 2 different hard drives. A: If you are a beginner of Java, please give yourself a break by not doing this. If you're experienced Java programmer, I don't think your boss will ask you to do this. Keep It Simple and Stupid (KISS). Please! But if you insist, figure it out! I guess it can be done, and here is something which might help: Q. How to create my own package, how to call my class in another package? Q. What are the rules to name a Java file without public class defined in it? A: Everyone knows one Java file only can contain one public class, and the file must be named as the name of the public class name. But how about Java file with no public class?
No restrictions on name of Java file without public class defined. If you have a class with a main, you'd better name the file with that class name for your own convenience. However, this is not required. Test this out! // D.java class A {} class B {} class C {} class E { public static void main(String[] args) { System.out.println("Strange thing in E."); } } class F { public static void main(String[] args) { System.out.println("Strange thing in F."); } }
It is called D.java. You can run it in 2 ways: java E //output: Strange thing in E. java F //output: Strange thing in F. If you think carefully, there are good reasons for this. Testing is one of them. Q. Why cannot I use private access modifier in my interface definition? A: See original discussion here. Everything declared in interface are implicit or explicit public. If you don't put anything there, they are public (not default). No access modifiers other than public allowed. Q. Where can I find Java Grammar? A: The best answer is to read the JLS, THE JAVA LANGUAGE SPECIFICATION from the source. Java grammar is officially defined there. For your academic type, there is an interesting site, called Lykkenborg eZine. The author tried to make Java grammar easier to navigate.
Primitive Types in Java and Type Casting Q. What is void? Is void a Java type? A: void means nothing. You mark a method void means the method returns nothing. It is the same in Java/C++/C/C#. void is not a type in any of the languages. Q. What is the difference of signed and unsigned integer? A:
It is the interpretation of the first bit of the integer number been represented. If it is signed, the first bit is 0 means it is a positive number, 1 means it is negative. If it is unsigned, the first bit is just another bit, either to add (1) or not to add (0) 2n to the value of the number. n is the bit location, 0 based counted from right to left. Here is a binary representation of two bytes: 1111 1111 1111 0100 Signed : -12 unsigned: 65524 0000 0000 0000 1100 Signed : 12 unsigned: 12
If you don't understand how the negative number comes out, read the super article Two's complement. In java, only char is unsigned, others like byte, short, int, long are all signed. In other languages like c/c++, all other types have a unsigned brother, char is always unsigned.
Q. Why char range is 0 to 216-1? A: 0 to 216-1 0 to 65535 0 to 1111 1111 1111 1111 '\u0000' to '\uFFFF' All of above are equivalent, since char is unsigned 2 byte integer. For the first one, use your scientific calculator to do a little math. You can use the following to understand it too. 1111 1111 1111 1111 + 1 = 1 0000 0000 0000 0000 = 216 Q. The size of long is 64bits and that of float is 32 bits. then how it is possible long to float without type casting it? eg. long l=12345678; float f = l; // ok to compiler
A: Interesting question!!! The internal representation of integer types (byte, short, char, long) and floating point number (float, double) are totally different. Converting from long to float is not a narrowing conversion. Even it may lose some significant digits. See the following table for details: Primitive Data Types
type
default value when it is a class member
# of range bits
8, 1 true Boolean bit used
false
false
char
16
'\u0000'
'\uFFFF'
'\u0000'
byte
8
-128
+127
0
short
16
-32,768
+32,767
0
int
32
-2,147,483,648
+2,147,483,647
0
long
64
-9,223,372,036,854,775,808 +9,223,372,036,854,775,807 0
float
32
-3.40292347E+38
double 64
+3.40292347E+38
0.0
+ 0.0 1.79769313486231570E+308 1.79769313486231570E+308
Q. Why char c = 3; compiles, but float f = 1.3; error out? A: char c = 3; byte b = 300; short s = 300; int i = 30000; are assignments to integers(signed or unsigned) Compiler will do a range checking to see if those value are in the range of the variable, if it is, ok; otherwise, error out! float f = 1.3; float f = 1.3f; double d = 1.3; are assignments to floating numbers. The difference between 1.3d and 1.3f is the precision, not the range. 1.3 is default to double precision number, assigning it to a float will lose precision. It will need a cast! 1.3 is different than 1.30 in physics/science, since different precision implication. Distance d = 1.3 miles implies d is between 1.25 and 1.35 miles
Distance d = 1.30 miles implies d is between 1.295 and 1.305 miles, which is a lot more precise measurement. Of course, not everybody follows the convention. Q. What are the variable initialization rules in Java? A: Here we are: •
•
Member variables (both static and instance) are initialized implicitly by default: 1. Most primitives except boolean are default initialized to zero, not null! 2. boolean variables are default initialized to false, not zero, not null! 3. Only object references are default initialized to null! 4. Final varibles must be initialized explicitly in declaration or constructors (instance final variable.) Local varibles are not initialized 1. They are not default intialized to anything, unless programmer initialize them explicitly! 2. It is not compilable if you use them before assign them a value!
Q. Why byte to char, or float to long are narrow conversion defined by JLS? A: class My{ static long l; static float f; static char c; static byte b; public static void main(String[] ss) { b=c; //not compilable c=b; //not compilable either l=f; //not compilable f=l; //OK } }
Since char is 2 bytes unsigned integer, assign it to 1 byte signed integer will possible loss precision. Opposite is true too, since the negative part of byte will be re-interpret to positive and possible loss precision. The float to long should be more obvious, since its decimal part will be lost. Q. How many bits represent a boolean variable? A: Since boolean only has 2 states (true, false), one bit is absolutely enough for storing it. However, in memory, we have no way to represent the address of each bit as a variable address / reference, then we have to use one byte (8 bits) to make the variable
addressable. In other words, we only use 1 bit, and leave the other 7 bits unused. To prove this theory, run the following program TestBoolSerialize.java. The output file Bool.tmp and Byte.tmp will be the same size, but Short.tmp will be double the size. You may need to run 1 section a time if you run out your memory. Don't need to worry too much about internal representation is one beautiful thing of Java. The programmer don't need to actively allocate/return memory like in c/c++. Don't you remember the pain of using sizeof() in c/c++, because of the pointer arithmetic, etc? There is no sizeof() in Java. My above program TestBoolSerialize.java actually does the trick of sizeof() to reveal the secret of Java for you. •
Q. What is type cast, can you give some simple example? A: *** type cast *** Cast the type of a variabe from one type to another, of course, it must be legal in Java/C++ etc. Examples follow: long l = 300L; int i = (int)l; // cast a long to an int class A {} class B extends A {} // will compile and run fine A a = new B(); B b = (B)a; // cast A reference a to a B reference b // runtime fine since a is actually a B // will compile fine and ClassCastException will be thrown on runtime A a = new A(); B b = (B)a; // cast A reference a to a B reference b // runtime exception will be thrown since a is not really a B
Q. How to cast between objects? How about interfaces? A: 1. Upper cast from subclass to supercalss, no need to cast, since the ISA relationship. OakTree is a Tree. 2. Down cast from superclass to subclass, an explicit cast is needed to avoid compile time error. If you cast Tree to OakTree, it would possibly be right, but not necessarily, since this particular Tree actually might be an AppleTree. In that case, a ClassCastException will be thrown out at the run time
3. If you cast between siblings or even irrelevant classes, a compile time error results, since compiler has the type information of them. for example, if you cast a OakTree to an AppleTree, or even a Furniture, compile will error out. 4. However, there is a catch, if you cast to an interface, even they are irrelevant, and compiler might let you go without an error. See some interesting example and runnable code at TestCast.java Q. Why this code compiles OK, but throw ClassCastException at runtime? Base b=new Base(); Sub s=new Sub(); //Sub extends Base s=(Sub)b;
A: "Oversea Chinese is a Chinese", but not vise versa. "Chinese is not necessary an oversea Chinese, but possible." When you cast super to sub, compiler assume that you know what you were doing, since it is possible. However, runtime will find out b actually is not a Sub. Since Cat is an Animal, but Animal is not necessary a Cat, but it is possible a Cat. That is why downcast is allowed on compile time, since compiler assumes you know what you are doing. However, Runtime will find out this Animal is actually not a Cat. ClassCastException! Big time.
Q. What are the differences between char and byte? Why text file can be read back as byte streams? A: 1. Everything in computer are represented by 0's and 1's, every eight 0's and 1's can form a byte, that is why everything can be read in as byte streams. 2. byte is the smallest memory unit addressable. 3. How to interpret those bytes is the job of operation system, software, etc. 4. For Java primitive types, char is 16 bits unsigned integer, byte is 8 bits signed integer, short is 16 bits signed integer. 5. The difference between char and short is the interpretation of the first bit.
Q. A case study, why 3 is printed out? class Test { public static void main(String[] args) { Test t = new Test(); t.test(1.0, 2L, 3);
} void test(double a, double b, short c) { System.out.println("1"); } void test(float a, byte b, byte c) { System.out.println("2"); } void test(double a, double b, double c) { System.out.println("3"); } void test(int a, long b, int c) { System.out.println("4"); } void test(long a, long b, long c) { System.out.println("5"); } void test(float a, long b, int c) { System.out.println("6"); } } // output: 3 // think why?
A: Remember the following will help: • •
3 (integer type) is always default to int in Java. 1.0 (floating point number) is is always default to double in Java.
Explanation correct or wrong: 1. 2. 3. 4. 5. 6.
Wrong! Since 3 is int, int to short needs explicit cast. Wrong! Since all three parameters are wrong. Correct! Since numeric promotions are performed on 2nd/3rd parameters. Wrong! Since 1.0 is double, double to int needs explicit cast. Wrong! Since double to long needs explicit cast. Wrong! Since double to float needs explicit cast.
Java Objects Q. Why hashCode must be the same for two objects equal to each other? A: This is a complicated question. Let us discuss it slowly.
• •
• •
•
•
You must read the javadoc here first. Otherwise, we have no common ground. It is excellent reading too! HashTable or HashMap are fundamental data structure in computer science. The lookup speed is close to O(1), since we use hashCode to put (store) and look-up (retrieve) elements. See more detailed explanation on HashTable here! Equal objects must have the same hashCode! It is a must, not a choice. Otherwise, HashTable or HashMap will not work correctly! Different/unequal objects have different hashCodes or not, which has everything to do with the efficiency of HashTable/HashMap etc. It is a trade-off between time and space. Less collision will make look-up faster (saving time), but will use more memory (wasting space). The hashCode generation/look-up algorithm usually considers the sparcity of the hashTable to make the decision. However, since memory is so cheap now, people no longer pay too much attention to the algorithm any more, UNTIL you have an OutOfMemoryError, of course. Since Java made all of these behind the scene, it becomes more obscure to developers. Good or Bad??? I think the answer is BOTH! The good side is making coding easier, the bad side is some programmers don't understand them any more. In real programming life, you might need to code them yourself for efficiency or your application special needs.
• Q. How many objects is created in String case? A: Generally to say, please don't use String in Java to discuss creating a new object or not. It just waste your time since Java using String Pool. Here are two cases, read the comments, please! String s1 = "Hello world!"; // If "Hello world!" is in String pool, // no Object is created, otherwise yes, and put it in the String Pool. String s2 = new String("Hello world!"); // A new String object is definitely created.
Q. How to use clone()method, why my code throws CloneNotSupportedException? A: Make your class implements Cloneable interface, and override the Object.clone() method. If you don't override the Object.clone() method, the code will be compilable, but throws CloneNotSupportedException. Why, see the following code copied from JDK Object.java. protected native Object clone() throws CloneNotSupportedException;
Q. What does clone() method do? A:
The key concept you need to understand is the default implementation of clone() is a shallow clone(). The primitive type is cloned, for example, the hashCode() (type long) of the original and the clone will have the same value. If you change the clone's primitive type field value, the original will stay the same as before. But the reference type just clones the same object's reference. Therefore when you make a change in the data member object, the original and the clone will be both changed. I learned this the hard way. Then I had to write my deepClone() method to do my job.
Q. Can we cast an Object to cloneable? A: Yes or No It will compile, since compiler does not check interface casting. However, it will throw java.lang.ClassCastException at runtime. Try the following example. See more type cast example here TestCast.java class T { public static void main(String[] args) { Object o = new Object(); // compile ok, throw java.lang.ClassCastException at runtime Cloneable c = (Cloneable)o; // not even compilable // Object o2 = c.clone(); } }
Java Packages Q. How to start to define my own packages? Any suggestions? A: Suggestions: • • • •
Don't put your own stuff under jdk. Create a directory such as c:/myworkarea or c:/liuxia Create a stem directory, such as com/myco or org/myorg under your c:/myworkarea No Java files should be put in your stem directory, only packages All your code will start with a package statement, and put them under the corresponding directories. Examples: package com.myco.somepkg; package com.myco.somepkg.somesubpkg;
That will be a good start.
If I define a class in com.myco package as com/myco/MyClass.java, How do I compile and run it? In your c:/myworkarea directory: javac com/myco/pkg1/MyClass.java java com.myco.pkg1.MyClass
However, this is just to get you started. The better practice is using ant. Start to learn Ant now Q. How to create my own package, how to call my class in another package? A: Here is a runnable example with detailed explanation for you to play and practice. Package Usage Q. What should I do when we have class name conflict? A: Use fully qualified name. Bad naming causes problem, you need naming your class name carefully. Don't call them the same name as Java API classes. Another thing is make your class name meaningful. However, sometimes, it happens. There is a Date class defined in java.util package, but also java.sql package. When it does happen, use fully qualified name instead. Problem solved, always!!!! Examples for fully qualified names: java.util.Date java.sql.Date
Q. What are the rules and convention about package name? Why I got an error when I used WEB-INF as my package name? A: package name in Java is an identifier, therefore it has to qualify as an identifier first. Read JLS for rules of Java identifiers JLS 3.8 Identifiers To my limited knowledge of computer programming languages, I do not know any programming language which allows dash '-' as part of an identifier. Not in any of the followings: Pascal, c, c++, Fortran, c#, Ada, VB, Lisp, Java, ML, perl, ... It might be allowed in COBOL, but I'm not sure, since COBOL is a very loose language. I do not know COBOL. Any COBOL expert here? Help, please! The first problem for WEB-INF as a package name is dash '-', of course. The second problem is WEB-INF in tomcat or Java web component develop environment has special meaning, you cannot use it for anything else.In all of above, we are not talking about convention, but the rules. Read Java coding convention here: Code Conventions for the JavaTM Programming Language What are the differences? If you violate the convention only, your code should still compilable/runnable/workable, but not very good. Another thing you need to remember is that conventions are very subjective. A good convention in IBM shop might be considered bad in Microsoft or EDS.
Java Constructors Q. What does keyword this mean? A: keyword this is use in Java/C++/C# to refer to the object itself, just like "I" in human languages. Q. How to use super and this Java keywords? A: super(); this();
With or without parameters, only one of these is allowed as the first line in your constructor, nowhere else! However, super.method1(); this.field4;
do not have the above restrictions in your code. Q. How does the Java default constructor be provided? Is it the same as C++? A: If a class defined by the code does not have any constructor, compiler will automatically provide one no-parameter-constructor (default-constructor) for the class in the byte code. The access modifier (public/private/etc.) of the default constructor is the same as the class itself. Attention to former C++ programmers: It is very important to previous C++ programmers to know the differences between C++ and Java. C++ compiler will provide a no-parameter-constructor (defult-constructor) as long as you did not define one. Java only provide a no-parameter-constructor when your class does not have any construcor.Can you let me see it? Oh, yes, in where your class file is, type javap -private YourClassName
Your C++ programmer will be real happy to see the output very similar to a YourClassName.h Of course, j2sdk/bin or jre/bin directory must on your path. Q. Can constructor be inherited? A: No, absolutely not! Here is a good example. MyButton extends JButton, but did not add similar constructors, then you cannot call the constructor with String or ImageIcon. Please read the comments inside the code. import javax.swing.*; import java.awt.*; class MyButton extends JButton { int x, y; } public class MyFrame extends JFrame {
ImageIcon icon = new ImageIcon("btn.gif"); //Only default constructor works MyButton bn = new MyButton(); Container cpane; //JButton constructors are not inherited //MyButton bn = new MyButton("Btn Text"); // not work! //MyButton bn = new MyButton(icon); // not work either MyFrame() { cpane = getContentPane(); cpane.setLayout(new GridLayout(2, 1)); bn.setIcon (icon); //OK bn.setText ("Btn Text"); // OK bn.x=5; bn.y=10; JTextArea txtarea = new JTextArea("bn.x= "+ bn.x + "\nbn.y=" + bn.y); cpane.add(bn); cpane.add(txtarea); pack(); setVisible(true); } public static void main(String args[]) { MyFrame myfrm = new MyFrame(); myfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
Q. Does Java initialize static variable first when we instantiate an Object? A: Wrong question! Please do NOT mix static field initialization with Object construction or instantiation! • • •
static field initialization happens at class loading time, it only happens once, and once only. It might be changed long before your object instantiation time! When you compile and run a toy program, it might look correct. However, the real world programming is NOT a toy! Someone might think "what the article said should be correct at least once, at least correct at the first Object is instantiated." No, that is not necessary true either, since you might call on static method of that class long before the first Object is instantiated. The static value has been initialized and changed long before the first Object is instantiated.
Q. Why does my following code not compilable? class Base{ public int i = 0; public Base(String text){ i = 1;
} } public class Sub extends Base{ public Sub(String text){ i = 2; } public static void main(String args[]){ Sub sub = new Sub("Hello"); System.out.println(sub.i); } } // Compile error: // Sub.java:8: cannot resolve symbol // symbol : constructor Base ()
A: Because you did not explicitly call super(String) in Sub contructor, a default super() is added. However, the super class of Sub does not have a Base() constructor. ERROR! How to solve the problem? Two choices: 1. Explicitly call super(String) in Sub constructor 2. Add a no-param-constructor for Base() See the following detailed commented code, uncomment either one will work class Base{ public int i = 0; /* ----------------- choice #2 public Base() { // do whatever } */ public Base(String text){ i = 1; } } public class Sub extends Base{ public Sub(String text){ // super(text); //-- choice #1 // problems here!!! // since if you don't, then a default // super(); //is generated by compiler i = 2; } public static void main(String args[]){ Sub sub = new Sub("Hello"); System.out.println(sub.i); } }
Q. Why does my following code not compilable? How to fix it? class A {
int i; A(int k) i = k; }
{
} class B extends A { public static void main(String args[]) { A a = new A(10); System.out.println(a.i); } } /* Compile Error: C:\>javac B.java B.java:7: cannot resolve symbol symbol : constructor A () location: class A class B extends A { ^ 1 error */
A: You need to understand how compiler works The problem of your code: 1. You did not define a constructor for B, compiler will define a default noparameter constructor for you. 2. The compiler defined no-parameter constructor will auto-call superclass A noparameter constructor. 3. The superclass A no-parameter constructor does not exist!!!! 4. Compile ERROR, big time!!!!!!!!!!!!!!!!!!! How to fix it, I give you three choices follows: solution #1, define a no-parameter constructor for A class A { int i; A() { } A(int k) { i = k; } } class B extends A { public static void main(String args[]) { A a = new A(10); System.out.println(a.i); } }
solution #2, define a with-parameter constructor for B, which in turn calls withparameter 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 withparameter constructor for A class A { int i; A(int k) { i = k; } } class B extends A { B() { super(56); } public static void main(String args[]) { A a = new A(10); System.out.println(a.i); } }
Q. Can I specify void as the return type of constructor? It compiles. A: No, you cannot! However, why it compiles? Yes, it you code it tricky enough, it will compile without any error message!Surprised? Proved? Ha, ha, Roseanne is wrong?! Wait a minute, hmmm... it is not a constructor any more! It is just a method happen to have the same name as the class name Try the following code! Please! It will be a very very interesting experience and lots of fun too! public class A { // this is a constructor of class A public A(int i) { System.out.println("We are in contructor: A(int i)"); System.out.println("The i value is " + i); } // this is a method A void A() { System.out.println("We are in method: void A()");
} public static void main(String[] args) { // They are fine here! A a1 = new A(3); a1.A(); // Compile time error // cannot resolve symbol constructor A() // A a2 = new A(); } } // // // //
output We are in contructor: A(int i) The i value is 3 We are in method: void A()
Access Modifiers, etc. Q. What is abstract method? A: Method marked as abstract means the method has no body! The subclass need to implement all abstract method to become usable non-abstract class. public abstract void saySomething(); // must have no body here!
Q. Is it a must for a abstract class to have a abstract method? A: No! All methods defined in interfaces are abstract. All classes which have abstract method(s) must be declared abstract, but not vice versa. Q. Can one object access a private variable of another object of the same class? A: Yes! One object can access a private variable of another object of the same class. The private field can be accessed from static method of the class through an instance of the same class too.Here is an example: public class Test1 { private int i; Test1(int ii) { i = ii; System.out.println("Self: " + i); // to avoid infinite recursion if (i != 3) { Test1 other = new Test1(3); other.i++; System.out.println("Other: " + other.i); } }
public static void main(String[] args) { Test1 t = new Test1(5); // The private field can be accessed from // static method of the same class // through an instance of the same class System.out.println(t.i); } }
Q. Several questions about static: a) Can a static variable be declared within a method? b) Can a static method contain an inner class? c) Can a static method contain an static inner class? A: a) No, not in Java, but yes in C++ b) Yes c) No The simplest way to have your doubts clarified is to write a short program, then compile it to see the result. CODE, Code, code, ... please! An example here: class Test { void method() { //static int i = 3; } static void smethod() //static int i = 3; class local { } /* not compilable static class slocal } */ } }
// not compilable { // not compilable
{
Q. Why the following code not compilable? Do we need to initial final variable explicitly? public class Test{ static int int final static int final int }
sn; n; fsn; 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 final static final
int int int int
sn; n; fsn = 3; fn = 6;
} public class Test{ static int int final static int final int
sn; n; fsn; fn;
static {fsn=6;} {fn =8;} } public class Test{ static int int final static int final int
sn; n; fsn; fn;
static {fsn=6;} Test(){ fn =8; } Test(int pn){ fn =pn; } }
Q. Can we declare an object as final? I think I still can change the value of a final object. A: final variables cannot be changed. final methods cannot be overridden. final classes cannot be inherited. However, there is something easily to be confused. There is no final Object in Java. You cannot even declare an Object in Java, only Object references. We only can have final object reference, which cannot be changed. It is like that the address of your house cannot be changed if it is declared as final. However, you can remodel your house, add a room, etc. Your house is not final, but the reference to your house is final. That is a little confusing. By the way, use finals as much as possible, but do not overuse them of course. It is because compiler knows they are not going to change, the byte code generated for them will be much more efficient. Q. Can we use transient and static to modify the same variable? Does it make any difference in Object serialization? A:
Yes, we can use transient and static to modify the same variable. It Does not make any difference in Object serialization. Since both transient and static variables are not serializable.See your exausting example at TestSerialization.java Q. What happens if we don't declare a constructor as public? Is it a useful strategy somewhere? A: Following discussion is based on the assumption of that your class is declared as public and at least has some public members, and the other package imports your class or using full-qualified names to use your class. 1. You cannot construct an instance of the class by using this constructor in another package. 2. If you have other constructors declared public, you still can construct an instance of the class by using other public constructors in another package. 3. If all your constructors are not public, then the class cannot be constructed in packages other than the package it was defined. 4. If the other package gets a reference to it, its public members still can be used. Singleton Design Pattern is a good example for it. We even use private construtor intentionally.
Q. In a non-static inner class, static final variables are allowed, but not static variables! why? A: When a variable is static final, actually, it is not a variable; it is a constant. Compiler will treat it differently. Q. Can final and transient be used together? Why? A: Yes, they can. final variables cannot be changed. final methods cannot be overridden. final classes cannot be inherited. transient variables cannot be serialized. They are independent of each other. A variable can be final or a constant (an oxymoron, right? ), and transient or not serializable. I actually figured out a good reason not to serialize final variables.Serializing objects are mostly for transferring data. The both side of transferring will know the Class object, know the constants in most of the cases, with the exception of initialized finals in constructors by using the parameter value. Not Serializing the final will certainly save transferring time. Using final and transient together will certainly have some advantages in distributed computing. And, please remember, putting final and transient together is an option, not a requirement.
Q. Why null variable can access static member variables or methods? A: When you call a static data member or method, all it matters is right type. See example here // ST.java class ST { static int n = 3; static int getInt() { return n + 35; } public static void main(String[] args) { ST st = null; // st has the type of ST System.out.println(st.n); // 3 System.out.println(st.getInt());// 38 // the above lines are equivalent to the followings System.out.println(ST.n); // 3 System.out.println(ST.getInt());// 38 } }
Q. Should we hide private method defined in the superclass by defining the same name and signature method in the subclass? A: No. If super class defined a private method, it hides itself; nobody else can see it or use it. That is exactly what private means. It does not need a subclass to define a same name and signature method to be hided!!!If the subclass use the same name and signature to define another method, it does not hide anything, it is just itself and totally irrelevant with the super class same name method. In addition, it should be only considered a bad-coding style, even it is legal.Please read everything about hiding here! a section in JLS2 Q. Why I got IllegalAccessException when I try to use reflection or dynamic proxy to access some package level methods from another package? A: Why not? Do you think what you get is the reasonable behavior of Java? OR Do you assume Proxy or reflection should break the rule of Java, and open a backdoor to a class, and let it do something, which it is not supposed to do? Q. What is modifier for the default constructor implicitly generated by Java compiler? A: The default constructor implicitly generated by Java compiler should have the same accessibility as the class. i.e. public class will have a public default constructor, package
"friendly" class will have package "friendly" constructor, unless you explicitly define it otherwise.See Package usage example for details.
String and StringBuffer Q. What is the difference between String s = "hello"; and String s = new String("hello"); ? A: Read Sun's explanation here: http://java.sun.com/docs/books/tutorial/java/data/stringsAndJavac.html Q. Why String and StringBuffer works differently, discrimination? // Test.java public class Test { public static void main(String[] args) { String s1 = new String("hello"); String s2 = new String("hello"); StringBuffer sb1 = new StringBuffer("hello"); StringBuffer sb2 = new StringBuffer("hello"); System.out.println("String: s1.equals(s2) = " + s1.equals(s2)); System.out.println("StringBuffer: sb1.equals(sb2) = " + sb1.equals(sb2)); } } // output /* String: s1.equals(s2) = true StringBuffer: sb1.equals(sb2) = false */
A: Since String class overrides the equals() method of Object class, and StringBuffer does not. Read here: equals method and check the JDK doc for String and StringBuffer too. Q. How does Java String concatenation, or the overloaded + between different types, work? A: Go to your JDK1.2.2/JDK1.3 directory, find src.jar, unjar it. Then you can see all source code of JDK.Goto src\java\lang, to find StringBuffer.java and String.java. Search for append in the beginning comments of StringBuffer.java, then follow the lead, you will find out all the secrets you are interested in. "If you give me a fish, You feed me for the day. If you teach me how to fish, you feed me for life."
Q. Does "+" use in String concatenation affect efficiency? A: Traditional answer: Yes. Actually answer: No •
•
Traditional answer: Yes. Why? "a" + "b" + "c" is bad expierence because in memory the JVM will create "a", "b", "ab","c", "abc" which here, "ab" is a waste...Therefore you should always use StringBuffer. Actually answer: No. Why? From SLS at http://java.sun.com/docs/books/jls/
15.18.1.2 Optimization of String Concatenation An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.
Q. Why are outputs of these two statements so different? System.out.println(6 + 4 + " = sum"); // 10 = sum System.out.println("sum = " + 6 + 4); // sum = 64
A: • • • •
•
•
Java evaluates the expression inside println(expr) first, then convert it to a String. When Java evaluates the expression, it follows the left-to-right rule. "+" operator is overloaded in a very intuitive way just as in most other languages. In 6 + 4 + " = sum": from left to right, evaluates 6 + 4 first, two integer adds, 10 resulted. Then 10 + " = sum", int plus a String, String concatenation assumed, converts 10 to a string, then ... In "sum = " + 6 + 4: from left to right, "sum = " + 6, String plus an int, String concatenation assumed, converts 6 to a String, concatenates them together, become "sum = 6". Then repeats the same process with "sum = 6" + 4. You know the answer. String concatenation process actually is finished by a class StringBuffer. If you want to know the details, read the source code of jdk: StringBuffer.java. It is highly recommended for you to do that.
Methods Overloading and Overriding Q. What is the basic difference between the concept of method overloading and overriding? A: They are totally irrelevant except the name similarities in two senses. sense #1: English words overriding and overloading both have "over" inside sense #2:overloading methods will have the "same name" but different signature. overriding methods will have the "same name" and same signature. Except these above, there is nothing in common between them. Please read some more from the following QAs.
Q. Can overloaded methods in derived class hide the same name methods (with different signature) in base class? A: When methods are defined with the same name, but different signature, they are just name overloading, nothing can hide anything else. It is irrelevant it is in a derived class or not. 1. American people drive on the right side. 2. You are right on this topic. 3. He will be right back. English word right is overloaded here, we understand the difference by the context. Compiler understands the method overloading by the signature, which serves the same purpose as context, but more reliable, since compiler is not as intelligent as you are. If derived class (subclass) defines a non-private method with the same name and same signature as the non-private method defined in base class, then it is method overriding, polymorphism comes into play. Late binding/Runtime binding will happen.Never mix these two words overriding and overloading, please. Q. Can overloaded methods be override too? Static binding or dynamic binding? A: Yes, of course! In compiler point of view, overloaded methods are totally different methods. Because compiler identifies methods by their name and signature, you know overloaded methods must have different signatures. Derived classes still can override the overloaded methods. Polymorphism can still happen. Compiler will not binding the method calls since it is overloaded, because it might be overridden now or in the future. It is compiler's responsibility to check the caller
class has the method being called. It is the runtime's responsibility to call the right method along the hierarchy from bottom-up according to the real Object type identified. Q. What are the differences between overloading and overriding? Are they both concepts of polymorphism? A: No, overloading is NOT a concept of polymorphism. Let me try a short one about overloading. The approach is like you take the test, cross out something obviously not correct, before you decide what is correct. 3 + 5 3.0 + 5.0 The plus (+) operator is overloaded long before even OO concepts came into play in computer sciences. It is in Fortran (the first high level computer language) for sure. 1. 2. 3. 4. 5. 6. 7.
American drives on the right. British drives on the left. Maha Anna is right on this topic. I'll be right back. These are right angle triangles. You have the right to disagree with me. He is a right extremist. Actually, you can even overload the English word right to mean a dog in certain communication circle. Just thinking a scenario, you name your dog as Right, then in your family, when you or your kids talk about Right, the most of the time, it is referring to the dog. And it is a valid overloading; no body will put you in jail or even criticize you for your use of English word right this way... 8. ...
The English word right is overloaded here. All natural languages are overloaded long before computer even invented. Polymorphism is a very specific OO concept, which has nothing to do with overloading. You really need to read a good OO book to understand it. It is too large a job for me to write about it here. There is so much misunderstanding out there on this topic, a lot of them are in published books. Like Marcus said: "Don't believe everything you read." If you don't believe what you read here by Roseanne, I'm OK. P.S. The word Polymorphism itself in natural languages can be overloaded too like the Right example in English. You can overload the word polymorphism with whatever meaning you want it to mean. However, I still agree with most computer scientists' narrow and precise definition of polymorphism. If you don't agree with me, no more arguments are needed; we all can rest in peace...
Q. When ambiguity exists between method calls, how does compiler resolve it? Why String version of the method is called instead of the Object version in the following example? // Overloading.java public class Overloading { public void method(Object o) {
System.out.println("Object Version"); } // String is an Object, but a specific Object public void method(String s) { System.out.println("String Version"); } public static void main(String args[]) { Overloading test = new Overloading(); // null is ambiguous to both methods // The more specific one is called test.method(null); // String Version } }
A: The answer is in the comments of above code; just remember that when ambiguity exists between method calls, compiler resolves it by choosing the more specific ones. If it does not work, it will error out. Why String is more specific than Object? This is a Basic OO concept about generalization/specialization, read here for more specific information. Here is a brief: OakTree is a specific Tree. Cat is a specific Animal. String is a specific Object. Subclass ISA specific Baseclass. Q. An interesting example of ambiguity when program calls overloaded methods A: There is no exact match between eat() methods. However, the JVM know which one to call. There are 3 eat() methods, which create the ambiguity for illustrating the concepts. Read the comments in the code. public class EatDesertTest { void eat(Dessert d, Cake c){ System.out.println(" eat(Dessert d, Cake c)"); } void eat(Pie d, Dessert c){ System.out.println("eat(Pie d, Dessert c)"); } void eat(ApplePie a, Cake c){ System.out.println(" eat(ApplePie a, Cake c)"); } public static void main(String [] args){ ApplePie anApplePie = new ApplePie(); ChocolateCake aChocolateCake = new ChocolateCake(); EatDesertTest edt = new EatDesertTest(); // three eat() are all correct.
// but eat(ApplePie a, Cake c) is the most specific one edt.eat(anApplePie, aChocolateCake); // eat(ApplePie a, Cake c) } } class } class } class } class } class }
Dessert { Pie extends Dessert { ApplePie extends Pie { Cake extends Dessert { ChocolateCake extends Cake {
Q. Can overloaded methods have the same signature but different return type? A: No, absolutely not! In any programming languages, Methods overloading only applies to methods with different signatures. If same signature, there is only one method, two return types is impossible for one method. Try 5-10 line of code in Java or C++, you get your answer.Read here from JLS 8.4.7 Overloading If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but different signatures, then the method name is said to be overloaded. This fact causes no difficulty and never of itself results in a compile-time error. There is no required relationship between the return types or between the throws clauses of two methods with the same name but different signatures. However, If we have two overloaded methods (which means they have the same name, but different signatures), they can have same/different return types, and/or throw same/different exceptions. Q. Can static method be overridden? A: No! The concept of overriding is binding at runtime, or polymorphism. Static is just on the opposite side of the equation, binding at the compile time, polymorphism does not apply to static method. Methods a Subclass Cannot Override A subclass cannot override methods that are declared final in the superclass (by definition, final methods cannot be overridden). If you attempt to override a final method, the compiler displays an error message similar to the following and refuses to compile the program:" ... "Also, a subclass cannot override methods that are declared static in the superclass. In other words, a subclass cannot override a class method. A subclass can hide a static method in the superclass by declaring a static method in the subclass with
the same signature as the static method in the superclass. " Quotation from Overriding Methods of The Java Tutorial See more interesting discussion and sample code here: Can subclass override methods that are declared static in the superclass? Q. Can constructor be overridden? A: No! No, constructor cannot be overridden. Constructor must have the same name of the class itself, can never be its ancestor's name. For constructor calling orders, read here: What is the calling order of constructors along the hierarchy, from child up, or from ancestor down? Q. Can you explain the result of the following example? Oh, my! class Base { public boolean foo(Base b) { return true; } } class Sub extends Base { public boolean foo(Sub s) { return false; } } public class Test { public static void main(String argv[]) { Base bb = new Base(); Base bs = new Sub(); Sub ss = new Sub(); System.out.println(bb.foo(bb)); //true System.out.println(bs.foo(bs)); System.out.println(bs.foo(ss)); System.out.println(bs.foo(bb)); System.out.println(ss.foo(bs)); System.out.println(ss.foo(bb));
//true //true //true //true //true
??? ??? ??? ??? ???
System.out.println(ss.foo(ss)); //false } }
A: The foo methods are overloaded in the Sub. In Base, there is only one foo method, and it is not overridden by the Sub! Overloading is fundamentally different then overriding. There is no polymorphism or dynamic binding here!!! All decisions are made at compile time!!! See detailed explanation in the same code below, documented! class Base { // There is only one foo method in Base!!! public boolean foo(Base b) {
return true; } } class Sub extends Base { // differnt signature, method overloading // there are 2 foo methods in the Sub public boolean foo(Sub s) { return false; } } public class Test { public static void main(String argv[]) { // bb is a Base ref to the compiler, Base obj at runtime Base bb = new Base(); // bs is a Base ref to the compiler, Sub obj at runtime Base bs = new Sub(); // ss is a Sub ref to the compiler, Sub obj at runtime Sub ss = new Sub(); // All these 4 lines are Base ref // call Base.foo(Base) method, and only one foo available // bs is a Base ref, and ss ISA Base ref too // Everything is fine!!! System.out.println(bb.foo(bb)); //true System.out.println(bs.foo(bs)); //true System.out.println(bs.foo(ss)); //true System.out.println(bs.foo(bb)); //true // bb, bs are both Base refs to Compiler // ss is a Sub ref // call Sub.foo(Base) which is inherited from Base System.out.println(ss.foo(bs)); //true System.out.println(ss.foo(bb)); //true // no doubt about this one, am I right? System.out.println(ss.foo(ss)); //false } }
• Are Java and C++ using the same rules on method overriding/overloading? Q. Are Java and C++ using the same rules on method overriding/overloading? A: Yes, they are basically the same. Here are two equivalent class A/B in Java and C++. Compare carefully! A.java public class public int return x } public int return x }
A { mtdA(int x) { + 3; mtdB(int x, int y) { + y;
} class B extends A { /* $ javac A.java A.java:23: mtdA(int) in B cannot override mtdA(int) in A; attempting to use incompatible return type found : double required: int public double mtdA(int x) { ^ 1 error public double mtdA(int x) { return x + 0.2; } */ // Compiled OK public double mtdB(int x) { return x + 0.2; } }
A.cpp class A { virtual int mtdA(int x) { return x + 3; }; virtual int mtdB(int x, int y) { return x + y; }; }; class B : public A { // $ g++ A.cpp // A.cpp:15: error: conflicting return type specified for `virtual double B::mtdA(int)' // A.cpp:2: error: overriding `virtual int A::mtdA(int)' /* virtual double mtdA(int x) { return x + 0.2; }; */
// OK virtual double mtdB(int x) { return x + 0.2; }; };
Basic OO concepts Q. What is abstraction, what is encapsulation? What is the difference? A: pine tree, apple tree, oak tree.... Abstraction: Tree They are all trees. Another way to express the same concepts is generalization and specialization.Capacitor, resister, wire, box, CRT, ... Encapsulation: television You don't care what are inside the black box, and how they interact with each other, as long as the television works. Another way to express the same concepts is information hiding. Q. Why we need to construct a Vector first, then we can call addElement method? A: See original discussion here. Since addElement(Object) is an instance method of class Vector. If we don't construct a Vector instance first, we cannot call instance method. You may askWhy we define addElement(Object) as instance method? The answer should be obvious. You might use different Vectors in different parts of your application. Each Vector might add very different Objects. Define addElement as static (class) method does not make any sense.Give you a simple analog, you build a home, which is an instance of Home class, then add a TV to your living room. The addTV() method must be called after you construct your home, in other words, an instance method. Do you want you TV to be a class static variable and used by all home owners. No, you don't, and it is also impossible in reality too. Q. When an instance of subclass is created, is an instance of base class created also? How many objects are created during the process? A: A short lessen on Inheritance: ~~~~~~~~~~~~~~~~~~~~~ Truth: FordCar ISA or "is a" Car.Think: Which one is generalization/specialization? (Answer: Car is generalization) Which one should be the base/sub class? (Answer: Car should be the base class)Fact: A FordCar was just made.Questions: true/false? A Car was just made. (Answer: true) How many objects (Cars) were created during this process? (Answer: one) ~~~~~~~~~~~~~~~~~~~~~There is only one object, but it contains all of the variables for the entire hierarchy. The reason being that the execution of a constructor causes calls
to the constructors all the way back up the hierarchy to java.lang.Object - as each constructor executes, it gets the memory and sets the variables as required for that class.Where I can learn more about this topic?Reading some good Java / C++ / OO books, pay attention to the inheritance (or generalization/specialization) part. This is a big and extremely important topic. Yes, it is more important than learning Java. "Nothing can replace the technique of reading a good book from front to back." Here is an excellent free book: Bruce Eckel's Thinking in Java, 2nd Edition Q. Another interesting example to illustrate the concepts. It might be controversial too. A: An Asian boy was born. A boy was born. An Asian was born. A human was born. A creature was born. All above statements are true. How many creatures were born during the process?
Only one! This very Asian boy inherited all its base class features as a boy, an Asian, as a human, and as a creature. If you happen to be a Darwinist, do not believe creation, if you are doing research on the development of human embryo, you might even understand how those constructors were called during the process. Q. When we should use static methods, when we should use instance methods? Which one is better? A: This should depend on what problem you need to solve. If the method is a long complicated scientific calculation, static method is the right way to do it. It makes the method available and easy to be used everywhere. That is exactly what Java Math class does. Go there, and see it.If the method is an individual behavior, such as putOnMakeUp() , it is very cultural/personal dependent. Putting it as static method would be almost meaningless. Of course, you can make a static putOnMakeUp() work fine if you are willing to pass 15 parameters to it, or pass a large struct including all cultural/personal information needed. Ah, we drive our time machine and go back to that magnificent procedural/structural paradigm era...
Q. What does multi-inheritance mean? Are the following examples multiinheritance? //1. class A{ //... } class B extends //... } class C extends //... } //2. class A{ //... } class B extends //... } class C extends //... }
A{
A{
A{
B{
A: No! They both are not multi inheritances. Conceptual explanation: 1. Apple is a Fruit. Banana is a Fruit. 2. Apple is a Fruit. FujiApple is an Apple. Why don't you just compile the code to see what is allowed??? The following code is not allowed!!!! class A{ //... } class B{ //... } // Sub extends both A and B is not allowed // Java does not support multi-inheritance!!!! // However, ........ you fill this out! class Sub extends A, B{ //... }
Multi-inheritance is perfect legal in C++ class A{ //... } class B{ //... }
class Sub : public A, public B{ //... }
• Q. When should I use inheritance, when aggregation? A: They are Two different relationships! He is a human, human has a heart! ISA: inheritance HASA: aggregation
Q. What is the differences between association and aggregation? A: Examples to illustrate the differences, they can both called as composition. •
•
•
Aggregation implies encapsulation (hidding) of the parts of the composition. Object aggregation is a natural way of representing a whole-part relationship, (for example, molecules are aggregates of atoms, Human has a Heart, Car has an Engine.) An Association is a composition of independently constructed and externally visible parts. When we associate classes or objects, each one keeps a reference to the ones it is associated with. For example: : MyWebsite has a link to OtherWebsite. MyWebsite doesn't have OtherWebsite, but only has a link. The difference of the two is more clear in C++, since you can have an Object of another class(Aggregation), or you can have a pointer to another class (Association). It is not so clear in Java, since both are references.
Q. Why upcast is wrong concept? A: upcast is a wrong word with wrong concepts, even many people or even some published books are using this word. AppleTree is a Tree, AppleTree don't need upcast to be a Tree. AppleTree atree = new AppleTree(); System.out.println((atree instanceof Tree)); // true! Tree anotherTree = new AppleTree(); // correect, since AppleTree is a Tree, no upcast at all!
Q. Why compiler forces me to downcast? Does compiler just ignore my instanceof logic? // Employee is superclass of Manager if (employee instanceof Manager){ Manager m = (Manager)employee; //If no cast, compile errors }
A: Yes, compiler does not read your logic to make decision. Compiler makes decision according grammar rules.
Manager is an Employee, however, Employee is not necessary a manager. Employee can be a cafeteria janitor or something else. If you don't cast it to Manager, compile error results. Compiler does not analyze your logic at all to make decision. Compiler makes decision according grammar rules. Unless you explicitly cast, which means you know what you are doing, compiler will tell you "NO!". However, do a instanceof check before casting is a very smart decision, since otherwise, you will encounter possible runtime exception - ClassCastException!!!! To prove compiler does not analyze your logic, see and run the following code. A Manager is just instantiated one line ago, explicit cast is still required. Compiler does not make decision according to your logic. No matter it is one-line-ago or 10000-line-ago. e is the type of Employee, assign it to Manager, explicit cast is required. class Employee {} class Manager extends Employee {} public class T1 { public static void main(String[] args) { Employee e = new Manager(); Manager m = (Manager)e; // if not cast, error! } }
Inheritance, polymorphism, static/dynamic binding, etc. Basics Q. Does subclass inherited all fields and methods from the superclass? Do they all accessible? A: Yes, then No. All superclass information has to be inherited to make subclass functional. However, not all superclass information are accessible or visible by subclass. Encapsulation or information hiding is a basic concept of OO. If superclass set some fields or methods private, they will be invisible by subclasses. Default fields or methods are only accessible by subclasses in the same package. Why do all superclass information must be inherited ? That is because subclass might be able to put its hands on the private fields through public or protected getters and setters. Also, some private method might be called inside of public/protected methods. Q. Which one of the methods defined in interface or class with the same name will be called? A:
There is no method in interface can be called. Only the actual implementation of that method in class, which implements the interface mentioned, can be called. Q. Can subclass override methods that are declared static in the superclass? A: No! " Methods a Subclass Cannot Override A subclass cannot override methods that are declared final in the superclass (by definition, final methods cannot be overridden). If you attempt to override a final method, the compiler displays an error message similar to the following and refuses to compile the program:" ... "Also, a subclass cannot override methods that are declared static in the superclass. In other words, a subclass cannot override a class method. A subclass can hide a static method in the superclass by declaring a static method in the subclass with the same signature as the static method in the superclass. " Quotation from Overriding Methods of The Java Tutorial When you should use this kind of "hide" technique? Don't use it unless your boss gives you the assignment!!! Then you have no choice. Something legal does not mean it is recommended. Copied from Sun's Code Conventions for the JavaTM Programming Language Quote:
Avoid local declarations that hide declarations at higher levels. For example, do not declare the same variable name in an inner block: An interesting example here: class Base { static void doThis() { System.out.println("Base static doThis()"); } void doThat() { System.out.println("Base instance doThat()"); } } class Sub extends Base { // This is static method defined in the Sub class // which does not override the Base doThis() // only hide it. // proved in the Test.main() static void doThis() { System.out.println("Sub static doThis()"); } // This is instance method defined in the Sub class // which does override the Base doThat()
void doThat() { System.out.println("Sub instance doThat()"); } } public class Test { public static void main(String[] args) { // base is an instance of Sub Base base = new Sub(); // legal cast both at compile and run time Sub sub = (Sub)base; base.doThis(); //Base static doThis() base.doThat(); //Sub instance doThat() sub.doThis(); sub.doThat();
//Sub static doThis() //Sub instance doThat()
//Think why, try to understand the following concepts //static binding : bind at compile time //Dynamic binding : bind at run time } }
Q. If subclass overrides the methods in super class, can subclass call the super class method? A: Yes, you can. However, that is the subclass it self's choice. Outsider does not have this choice. You can see it clearly from the following example. class Sup { void m1() { System.out.println("m1 in super"); } } class Sub extends Sup{ void m1() { super.m1(); System.out.println("m1 in sub"); } } public class T{ public static void main(String arg[]) { new Sub().m1(); } }
Q. Are non-static fields (variables) dynamically bound?
A: No, fields or variables are always bound at compiling time. • •
Fields or variables is static bound (decided) at compile time. Non static method is dynamically bound (decided) at runtime.
In theory of programming languages, there is a deep explanation for this. Variables must be bound at compile time. However, I think remembering the fact is much more important than knowing why... Q. What is hide(a variable or a static method) means in computer languages (such as Java)? Should we do that? A: Hide basic is a scope issue, when we have the same name in a smaller/more local scope, the smaller scope one will hide the upper ones. Here is a real life example: If you call your daughter Oprah Winfrey, then in your home, or in your daughter's kindergarten, people talk about Oprah Winfrey will refer to your daughter. The popular talk show host Oprah Winfrey will be hidden, unless you refer her as talk show host Oprah Winfrey. This example tells you three things: 1. Hiding is a scope issue. 2. Hiding cannot be complete/absolute. 3. Hiding is not good practice, since it causes confusion.My suggestion is don't call your daughter Oprah Winfrey, or don't practice hiding in your Java or C# or ... programming. The followings are two Java programs to illustrate the hiding concepts. // hiding a instanse variable class A { int i = 3; void method1() { // this i will hide the member i // bad coding practice int i =5; System.out.println(i); //5 // however, it can still be accessed by using this.i System.out.println(this.i); //3 } } // hiding a static method class A { static void method1() { System.out.println("in class A's static method1"); } } class B extends A { // this will hide the static method1 in class A
static void method1() { System.out.println("in class B's static method1"); } public static void main(String[] args) { // since we are in class B's scope // call method1 directory will refer to B's method1, // A's method1 is hidden method1(); //in class B's static method1 // However, we still can call A's method1 even in B's territory A.method1(); //in class A's static method1 } }
Q. Can you give an example to illustrate the difference of static/dynamic binding and static method cannot be overriden? A: static method is bound (determined) at compile time. You can easily to find the difference by use the following example. Pay attention to the comments and the run results. class A { static void method1() { System.out.println("A.method1()"); } void method2() { System.out.println("A.method2()"); } } public class B extends A{ // will not override A.method1() static void method1() { System.out.println("B.method1()"); } // will override the A. method2() void method2() { System.out.println("B.method2()"); } public static void main(String[] args) { A a = new B(); // static bound with A.method1(), since a is A reference a.method1(); // A.method1() // dynamically bound to B.method2(), since a actually refers Object B a.method2(); // B.method2() } }
Q. Why the call to xy.amethod() calls amethod() in X instead of amethod() in Y in the following code? class X { public static void jout(String s) { System.out.println(s);
} static void amethod() { jout("In X, amethod()"); } } class Y extends X { static void amethod() { jout("In Y, amethod()"); } } class Z extends Y { static void amethod() { jout("In Z. amethod()"); } } public class Test public static void main (String[] args) { X xy = new Y(); X xz = new Z(); Y yz = new Z(); xy.amethod(); xz.amethod(); yz.amethod(); } }
A: All three amethod()s here are static methods. static method is Class method, which has nothing to do with your object instantiation, dynamic binding, or polymorphism, whatsoever. In other words, the 3 line of codexy.amethod(); xz.amethod(); yz.amethod();can be replaced by the following 3 lines without causing any changes:X.amethod(); X.amethod(); Y.amethod();Since compiler interprets them exactly like this. xy and xz are reference type of X. yz is reference type of Y.Just remember "static is not dynamic" probably will help some. Q. When base class calls a method, how could the run time knows to called the overridden method in the derived class? The object is not even constructed yet. A: Why? From the language theory, it is called deferred binding or dynamic binding or binding at run time. Compiler leaves the decision to run time. To make the decision at run time, you don't need the object built first. The only thing you need to know is the type of the actual object. In Java, the Class (not class) objects are loaded to the memory when it is first used. The run time knows it before any instance is constructed. In C++, the class methods virtual table is there for the same purpose. As you probably know, in C++, method are default to static binding, only virtual methods are dynamically bound. In Java, methods are default to dynamic binding, unless they are declared as static, private, or final.
Q. Does private method defined in base class participate polymorphism, if the derived class has a same name method? A: No, private method defined in any class will never participate polymorphism. If you want to confuse yourself, your boss, and your co-worker (and you might get fired for that too), and define same name private methods along the hierarchy, the compiler will treat them individually, as no relationship at all. If you call private method in your class, the method will be bound at compile time (not runtime).See the following example: // Base.java public class Base { public static void main(String[] args) { Sub sub = new Sub(); System.out.println(sub.g()); // 20, not -100 } private int f() { return 20; } protected int g() { // statc bound with Base.f() // compiler does not know any derived class has f() or not // and does not care either return f(); } } class Sub extends Base { // f() here has nothing to do with Base.f()!!! // In real world programming, never do this!!! public int f() { return -100; } }
Q. An example to illustrate private method is static bound at compiling time.n A: It is bad code in practice, but a good example to illustrate the concepts. • • • •
b is a Base reference, but points to a Sub at runtime. method1 is private in Base, therefore it is static bound at compiling time. Even Sub has a same name method, it is NOT an override of the Base same name method. To avoid confusion, please don't write code this way.
class Base { private void method1() { System.out.println("Base.method1()"); } public void method3() {
System.out.println("Base.method3()"); method1(); } } public class Sub extends Base { public void method1() { System.out.println("Sub.method1()"); } public static void main(String args[]) Base b = new Sub(); b.method3(); }
{
} // run output // Base.method3() // Base.method1()
Q. What kind of Java methods does not participate polymorphism? A: Polymorphism for Java method is always there except the following three situations: 1. The method is declared as final 2. The method is declared as private 3. The method is declared as static In those three cases, static binding will be performed by the compiler. Compiler does not have the knowledge, nor care about the method was, is, or will be overridden by none, one, or many subclass(es). The decision is made by the runtime, which is called dynamic binding. See next question, which discuss the same topic in a different angle. Q. What methods in Java is static bound? Please compare with c++ too. A: static, private, final methods are static bound. Those 3 methods does not participate polymorphism. In other words, they are not allowed to be overridden. In c++, virtual function can be overridden, others not. virtual in C++ --> nothing in Java nothing in C++ --> final in Java Q. Do we need an object reference to call a static method? A: No, not quite. See the following example. MyClass t = null; // the following two are equivalent t.aStaticMethod();//OK MyClass .aStaticMethod();//perfect
It is the class type; it doesn't need a "reference variable ". You can use a object reference to call a static method, of course, provided it has the right type. However, you don't have to. The above example clearly said that. t is not referring to anything but null, but has a MyClass type. If you know the old procedural programming, static method is equivalent to that, except in Java, we have a class Class. In Java, we can write magnificent old procedural program without any OO concepts by using all static methods. (No object reference at all). Wow, what a deal?
Harder Ones Q. What is the calling order of constructors along the hierarchy, from child up, or from ancestor down? A: The order is from child up. However, the super() is always implicitly or explicitly called as the first statement before any code in the child being executed. This might cause some confusion here. If you put a print statement in each of the constructor, the ancestor one will be output first. The following code will illustrate how it works.This is called LIFO, which one is called the first, will be finished the last. The child is called first, but it call its parent as the first statement, and the immediate parent will call its parent as the first statement too, and so on. Therefore the far ancestor, which is the Object will finish its constructor the first, then its immediate child, and so on. That is why the print statements will finish from the ancestor down. The calling stack is working this way. Last In, First Out (LIFO) public class Child extends Parent { public Child() { // super() is implicitly called here System.out.println("Child"); } public static void main(String[] args) { new Child(); } } class Parent extends GrantParent{ public Parent() { // super is explicitly called here super("Mother's parent"); System.out.println("Parent"); } } class GrantParent{ public GrantParent(String sWhosPrt) { System.out.println("GrantParent: " + sWhosPrt); } } // // // //
output GrantParent: Mother's parent Parent Child
Q. What is the static, instance initialization, constructor header, and code execution order? Why the radius prints out as 0 instead of 1 in the following code? //Ex from Bruce Eckel's Book "Thinking In Java" abstract class Glyph { abstract void draw(); Glyph() { System.out.println("Glyph() before draw()"); draw(); System.out.println("Glyph() after draw()"); } } class RoundGlyph extends Glyph { int radius = 1; RoundGlyph(int r) { radius = r; System.out.println( "RoundGlyph.RoundGlyph(), radius = " + radius); } void draw() { System.out.println("RoundGlyph.draw(), radius = " + radius); } } public class PolyConstructors { public static void main(String[] args) { new RoundGlyph(5); } } //Output is: //Glyph() before draw() //RoundGlyph.draw(), radius = 0 //Glyph() after draw() //RoundGlyph.RoundGlyph(), radius=5
A: The execution order is: 1. static variable initialization and static block executes only once when the class is loaded to the memory by JVM. 2. When constructor is called, the constructor header executes first before instance variable initialization and instance block execution. 3. instance variable initialization and instance block execute. 4. Code in the constructor executes. This is exactly what happened in your example (except no static stuff). The RoundGlyph constructor header executes first, which implicitly called default constructor of Glyph super(). The radius has not initialized yet; the value is 0. Then the radius is initialized to 1. Then the code in the RoundGlyph() constructor executes and changed radius value to 5. This kind of hair splitting trick, we'd better not know it, or don't tell your boss you know it. I probably learned from Mughal and Rasmussen's book, which I gave away after the test. Today, I wrote a little code to prove that I remembered it right. I usually do not pay a lot of attention to what is going to be on the SCJP test like Marcus Green does,
however, it is quite safe to say, questions like this will NOT be on your test.Warning: Don't try this at work! Q. Constructor or not constructor? Please explain why the output of the following code is null? public class My { String s; public void My(){ s = "Constructor"; } public void go() { System.out.println(s); } public static void main(String args[]) { My m = new My(); m.go(); } } //output : null
A: public void My() is not a constructor. The default constructor is called. s is still null by default.Constructor is not supposed to have a return type, even a void type. If it has, then it is not a constructor, but a method, which happens to have the same name as the class name. This is a tricky question just for testing your Java knowledge. Using class name as your method name is not considered as good code practice at work! Q. Base b = new SubBase(); How the compiler/Runtime to resolve the addresses of methods calls, Fields? // TestBinding.java class Base { String s = "string in Base"; void init(){ System.out.println("init() call in Base"); } } class SubBase extends Base{ String s = "string in SubBase"; void init(){ System.out.println("init() call in SubBase"); } } public class TestBinding { public static void main(String[] args) { Base b = new SubBase(); // static binding on instance fields System.out.println(b.s); //string in Base
// dynamic binding on instance methods b.init(); //init() call in SubBase } }
A: The above example plus comments actually told everything you need to know.When a field of an object is accessed using a reference, it is the type of the reference declared, which determines, which variable will actually be accessed. Static Binding -- Bind at compile time: The addressing of the field is determined at compile time. When a method is invoked on an object using a reference, it is the class of the current object denoted by the reference, not the type of the reference that determines which method implementation will be executed. Dynamic Binding -- Bind at run time: The addressing of the method is determined at run time.Notice to C++ programmer: In C++, only virtual methods (functions) are bound at run time. In Java, methods are default to dynamic binding, unless they are declared as static, private, or final. Q. If I remove the init() from the Base in the above question, I got a compile error: ""method init() not found class Base". Why? A: Incredible great question!! It will make you understand dynamic binding or polymorphism much better. If you remove init() from Base class, you actually take init() out of the polymorphism between Base and SubBase class. Compiler only know b is refer to a Base class, which does not have the method init(), compile time error!!! The Java compiler does not know, nor care who, when, where, how some other class is going to extends the Base class, there are some different named methods defined in them. And one of them happens to be called init(). They are totally irrelevant to the Base class.Remember SubBase ISA Base. Compiler does not care which child/grandchild/grand grandchild down the hierarchy b is actually referring to, and which init() it should call. However, they all have an init() (polymorphism). It is a runtime decision. Dynamic Binding.Dynamic binding, or binding at runtime only for those methods defined in Base class, either inherited or overridden by the subclass. The override can be already happened now or will happen in the future, the compiler does not care. Q. Here is another tricky code example for you to cracking on! Cover up the explanation to see you can explain it or not. class Base { int x = 3; public Base (){} public void showx(){ System.out.println("In base, x = " + x); } } class SubBase extends Base {
int x = 2; public void showx() { System.out.println("In SubBase, x = " + x); } } public class BindingTest { public static void main (String args[]){ Base b = new SubBase(); b.showx(); System.out.println("In Main, the (?) x = " + b.x); } } // output /* In SubBase, x = 2 In Main, the (?) x = 3 */
A: Danger: Do not try this at work! 1. In main(), b.x is bound at compile time, since b is declared as Base, x is 3. 2. In main(), b.showx() is bound at runtime, since b is actually a SubBase. the SubBase.showx() will be called. 3. In SubBase, call of x in method showx() is bound at the compile time, in class SubBase, x is 2. This is a typical tricky question, good for you cracking the concepts, but never write it on your job. You would be fired for that, no kidding!!!
Abstract Classes / Interfaces Q. Why do we need interface? A: This is an OO concepts, we define a protocol, then we can use it by contract, we don't care what is the implementation. Here is a commonplace example to illustrate the concepts. We have the PCI board in our computer, which define the interface, then all your SoundCard, GraphicsCard, etc. as long as they implement the interface, they are OK to plugin. Some illustrative sample code follows. Q. What are the implicit access modifiers in interface? A: •
All the variables defined in an interface must be static final, i.e. constants. Happily the values need not be known at compile time. You can do some
•
computation at class load time to compute the values. The variables need not be just simple ints and Strings. They can be any type. All methods in an interface are implicitly declared public and abstract. All variables in an interface must be constants. They are implicitly declared public static final.
Q. What are the differences between abstract classes and interfaces? A: • • • •
Interface is abstract, but not vice versa. There should be nothing implemented in interface. Abstract class can be partially implemented. A class can only extend one class; abstract class is included. A class can implement multi interfaces. You need to learn some basic OO concepts of inheritance and polymorphism, which apply not only to Java, but also to other OO languages, and even your real life.
Q. Can abstract class have static method? A: This example plus comment tells you everything. abstract class A { // OK static void doSomething() { } // illegal combination of modifiers: abstract and static // abstract static void doOtherthing(); } interface B { // modifier static not allowed here // static void doSomething(); }
Q. Can we pass an interface as parammeter to a method? If yes, how does it work? A: Yes, definitely. It is not only correct, but also is recommended. Since the implementation class can change, but the method will stay the same. There are tons of excellent examples in the Java collection framework. It is also very useful to implement some design patterns such as FactoryMethod Pattern. How to use it? When you make the method call, you must pass a concrete implementation of the interface to it. See the following example. // TestFace.java interface IFace{ void drawFace(); }
class RealFace implements IFace { public void drawFace(){ System.out.println("I'm drawing a beautiful face"); } } public class TestFace { // this code is aginst interface, and know nothing about // underneath implementation public static void callIFace(IFace face) { face.drawFace(); } public static void main(String[] args) { // if this code changes to a FaceFactory, you will not see class name RealFace here. // the class name can be read from an outside property file // then the code will become totally scalable in the future. IFace face = new RealFace(); //pass interface to the method callIFace(face); } }
Q. How to find out "What and Who" about an instantiation of an interface? A: Insert line like this. You will find out what is instantiated, and who did it. Statement stmnt = connection.createStatement(); System.out.println(stmnt.getClass());
This is the print output you will see if you are using JDBC-ODBC Bridge: class sun.jdbc.odbc.JdbcOdbcStatement
Try to do the same on enumeration or some other interfaces or abstract classes. Q. Why abstract method Graphics.drawString() can work without implementation? A: Excellent question! The following is a statement copied from API doc"The Graphics class is the abstract base class for all graphics contexts that allow an application to draw onto components that are realized on various devices, as well as onto off-screen images." Pay attention to the word devices, which means platform even hardware dependent. Then you find your jre\lib\rt.jar file on your machine, use some un-archive utility to see the names of some class files inside the jar file under sun\java2d\. Then you will know those abstract Graphics stuff is actually implemented in a device-dependent way. The following code will give you exact answer on WinNT: import java.applet.*; import java.awt.*; class TestApplet extends Applet { public void paint(Graphics g) { g.drawString(g.getClass().toString(), 20, 30); // output: class.ms.awt.GraphicsX } }
Q. What is the relationship between static and interface? A: static and interface: 1) Inner interfaces are implicitly static, no matter you put static modifier or not. Attention: inner interfaces are very rarely used. 2) Outer interface are NOT static, just like outer class. 3) All members (attributes & methods) of interface are implicitly public. 4) All attributes defined in interface are implicitly static and final. 5) All methods defined in interface are NOT static. 6) All classes defined in an interface are implicitly static Q. Can interface be extended? A: interface can be extended by another interface, but not by a class. For anonymous class, it can be confusing. e.g. interfacename ref = new interfacename() { //implementation code here }
The new anonymous class defined here is still implementing the interface named interfacename, not extending the interface. Q. Is it possible that we can run an abstract class with a main()? A: Yes, as long as you do not instantiate the abstract class or call its abstract methods. abstract class cannot be instantiated. However, if the main method only calls static method of the class, you can run it just like you run any C program. See the following example public abstract class A { static public int sum(int a, int b) { return a + b; } abstract public void aMethod(); // abstract static combination not allowed // abstract public static void aStaticMethod(); public static void main(String args[]) { System.out.println("Sum of 3 and 5 is : " + sum(3, 5)); // The following code will not be compilable // A a = new A(); // a.aMethod(); } }
•
Inner, Local, Anonymous Classes Q. Select the correct anonymous inner class declaration? A) B) C) D)
new Outer.new Inner new Inner() { } new Inner() Outer.new Inner()
A: All A) C) D) are not anonymous, all the classes have a name called Inner. They are not declarations, but call of their constructors. Only B is anonymous class declaration, as well as its constructor calling, since the anonymous class extends a class called Inner. The new anonymous class is defined with an empty body. Remember, anonymous class is always defined with its constructor calling. You cannot call its constructor anywhere else, since it does not have a name. However, in practice, you should not do that, it violates all the coding standards in the world, even though it is legal and grammatically correct. Q. What modifiers are legal to use to modify a nested member class? A: The compiler says: public class Test { public static void main(String argv[]){ } // all ok but one public class MyInner1 {} protected class MyInner2 {} private class MyInner3 {} class MyInner4 {} final class MyInner5 {} static class MyInner6 {} abstract class MyInner7 {} // not compilable //transient class MyInner8 {} }
Q. Is it possible that an anonymous class instance is referred outside of its scope of definition? A: :
The answer is yes. Anonymous class can be referred by the interface it implements or class it extends. Remember the ISA relationship? Which is definitely a SCJP test stuff. See sample code at InnerLocalAnonymous.java Q. True or false? "An inner anonymous class is always assumed to extend Object." A: false. Not always. Anonymous class always extends the class (1) or implements the interface (2) after the keyword new. In the second case, it extends Object.I assume that extends or implements can only be implicit, in case of anonymous classes.See the following example: import java.awt.*; import java.awt.event.*; class Outer extends Frame { public Outer(String s){ super(s); addWindowListener(new WindowAdapter(){ // anonymous class extends WindowAdapter public void windowClosing(WindowEvent e){ System.exit(0); } }); Button btn = new Button("Exit"); btn.addActionListener( new ActionListener(){ // anonymous class implements ActionListener, and extends Object public void actionPerformed(ActionEvent e){ System.exit(0); } } ); add(btn); } public static void main(String[] args) { Outer f = new Outer("Test"); f.setSize(400, 300); f.setVisible(true); } }
Q. Can we define a inner class in an interface? Is the following code compilable and/or useful? interface IFace { public class X { //It is not member inner class void method_Of_X() { System.out.println("Without static modifier, it is still static nested class."); }
} static class S { // static nested class. void method_Of_S() { System.out.println("static nested class."); } } }
A: Strange and surprising enough, the inner class defined in the interface is actually legal!!! I compiled the code and it was perfect fine with JDK1.2.2 and JDK1.3. I also compiled the code using jikes.exe, which means it is 100% JLS compliant. Attention: with or without static modifier, X and S are both static nested classes.I can even think of a situation in which it might be useful. A utility inner class will be used by all classes, which implement the interface. It would be a way of cheating on no-multi-inheritance in Java and actually made the interface fully implemented, provided the programmer is tricky enough. Interesting stuff, isn't it? However, In general, I think that using too many inner class or inner interfaces or even nested inner into another inner will causing spaghetti code, and it is just at least as bad (if not worse) as the old goto. I know someone who went to Sun's training class, and was told something similar. Many companies have some coding standard to limit their use. I think that is absolutely necessary! Q. "To create an instance of an member class an instance of its enclosing class is required." Is it true or false? A: False! Because member class include static and non-static (in other words, inner) enclosed classes. Quotation from JLS: "Member class declarations (?.5) describe nested classes that are members of the surrounding class. Member classes may be static, in which case they have no access to the instance variables of the surrounding class; or they may be inner classes (?.1.2)." Attention, here, or actually is an exclusive or (xor). e.g. "I will be at school or at home." Not both, right? Unless, you're in quantum mechanics... Q. What are the differences between static or non-static inner classes? A: 1. There is no such thing as a static inner class. There are top-level classes and nested classes, and nested classes are by definition divided into static and inner. 2. If it is static, it is not inner class, you can use it just as top-level class, but put a qualifier as EncloseingClass.EnclosedClass. 3. If inner class is a member of enclosing class, it must be attached to an instance of the Enclosing class, something like new EnclosingClass().new EnclosedClass(). 4. Local and anonymous classes are also inner classes, they can be defined in methods, initializers, which will be local to that enclosing scope. 5. Since the scope can be instance or static, Local and anonymous classes can be defined in an instance or a static context.
6. Attention: JLS2 has got rid of "Nested top-level class" confusing terminology now. 7. The correct name now is static member class, which in contrary to inner class (non-static member class) in JLS2 now. 8. See more in Classes in JLS2 9. See an Inner/Nested/Local Class Example here. It is just for you to play with, it is not comprehensive. Please pay attention to my "Don't try this at work" logo. 10. You can experiment unlimited combinations/permutations of nested/inner/static/local/anonymous/member/etc/... 11. Warning: Try to use less nested (static/non-static) classes, since it easily results error-prone, hard to maintain, spaghetti code 12. A summary table is suggested by Jim Yingst, I suppose you all know who he is. If you don't, click here . top-level class
top-level
static member class
nested
static member
(non-static) member class nested
inner member
local class
nested
inner
anonymous class
nested
inner
Q. An anonymous class cannot have any constructors. Is it true or false? A: False, anonymous class has one and only one constructor. You cannot explicitly define constructors for anonymous class, but compiler generates an constructor for it with the same signature as its parent constructor called. If the parent has more than one constructor, the anonymous will have one and only one constructor.Here is an example. After you compile it, then do javap Test$1, you will see the compiler generated one and only one constructor with the same signature as A constructor used, even class A has two constructors.Does anonymous class has a name? Oh, yes! The class name and the constructor would be, unsurprisingly, the same as the class file name. Test$1 in our example.What is javap? See here! // Test.java class A { int a; // 2 constructors for A A() { a = 100; } A(int aa) { a = aa; } public int m(int n) { return a + n; } } public class Test { public static void main(String[] args) { // Anonymous class extends A, override method m()
A oa = new A(12) { public int m(int n) { return a - n; } }; System.out.println(oa.m(5)); // 7 } } // javap Test$1 output /* C:\CODE>javap Test$1 Compiled from Test.java final class Test$1 extends A { Test$1(int); public int m(int); } */
Q. An anonymous class can only access static fields of the enclosing class. Is it true or false? A: false. An anonymous class object can access static and instance fields when it has an associated instance of the enclosing class (i.e. defined in a instance method). An anonymous class can only access static fields when it is in a static context (i.e. defined in a static method). " What it can't access is local variables (unless they are declared final). Attention: parameters passed to the method are treated the same as local variables, since it is passed by value and a local copy are really being used.See example at TestInnerEtc.java Search for "local" Q. Why does local class defined in a method only can access final local variables or final parameters? A: Local class (anonymous or with a name) defined in a method can be returned by the method, and it can live much longer than the method itself. See the question and answer above Is it possible that an anonymous class instance is referred outside of its scope of definition?However, the local variables are usually on the method calling-stack, and will be out of scope when the method returns. And the parameters passed into the methods are local copies of them (Read the topic pass-by-value). They will be out-of-scope too when the calling stack returns.However, if it is final, the local class can treat them as constant, and don't care what happens to the original variable any more.There is some complication in the concepts of Java, since only primitive types are really automatic variables (on the calling-stack). There exists some criticism on this practice of Java, since it is less efficient. This is beyond the topics of SCJP, and enters the programming languages theory domain.
Q. Can inner class extends outer class, or opposite? Why we should generally avoid using this technique? A: Yes, it is legal (inner class extends outer class, or opposite). However, you would be better off by not using these features.An advice from Sun's training class: Don't use inner class unless it is a very simple case. Actually, abuse of inner class is much worse than the abuse of old goto. This is my opinion, but not only mine. A lot of companies have very strict coding standard to eliminate abuse of inner classes too. You are better off without using inner classes in complicated projects. Inner class only gives you some convenience in simple cases, such as Adapter etc. Just consider the following scenario:We make total 10 levels of nested inner classes. 1) Let the 10th level inner class extends 5th level inner class, which in turn extends outer class. 2) Let 7th level inner class extends 4th level inner class, which in turn extends 2nd level of inner class. 3) The outer class extends 2nd level inner class (legal). 4) The 3rd level has 4 different inner classes, which extends different inner or outer class individually. 5) One of them has a method3(), which has a local class extends outer class. 6) ... The complexity can go on, and on, and on, and o... Unpredictable results are guaranteed. Got the picture? Remember, compiler is written by human beings, and uses certain grammar rules to do the job. The grammar rules only can handle limited complexity. The set of combination and permutation of things are unlimited. Grammar rules are not Newton's Law, or Einstein's Law of Relativity, which are not made by human, but we discovered them.Assumption of programmer will not do certain things (such as the above crazy stuff, even it is legal) will be made for cost, efficiency, and simplicity purposes. If you really want to, you can drive compiler crazy! In real life programming, if you find something does not work as you expected, try alternatives, or report a possible bug (or a undocumented feature ). And it will never be perfect, and it need not to be one either... Write good enough software. One more point: Why I was/am so passionate to express my view to against abuse of inner classes? It is because I'm a big believer of KISS. "Keep It Simple and Straight forward" or "Keep It Simple and Stupid". I'm sure a lot of visitors of this site are/will be leading software engineers/project leaders/manages/etc in the software industry. If some of you will think twice when you start to write code like some inner extends outer or opposite, it will be "music" to my ears. See original discussion here. A similar but on a different forum here. Q. A spaghetti and ravioli discussion, and inner class. A: Someone made this analogy:Procedural code can be like spaghetti - lots of long strands twisted and knotted around each other and very hard to follow.OO code can be like ravioli - a mess of small lumps with no obvious connection and no indication of what's inside.However, if you overuse the inner classes of Java, you can make a mixed and tangled spaghetti and ravioli. It would be really tastier than the old procedural code with the famous goto.
Collection Classes Q. What are the differences between Collection, Collections, and Java collections framework? A: Confusing, Isn't it?Java Collections Framework: A generic name given to Java API of collections classes/interfaces in java.util package. Root interfaces of this API are Collection and Map. See Trail: Collections of Sun Tutorial for details.Collection and Map: Root interfacesCollections and Arrays: Two classes with all static utility methods. They are NOT interfaces. Q. Can two different keys map to the same object elements? If yes, can you give an example? A: The answer is YES. In the real world, that is easy. You may have a nickname and an official name or even a fake name , they can be two/three keys in the map, and actually are all mapped to the same physical person: YOU. See the following code example: import java.util.*; public class TestMap { public static void main(String[] args) { HashMap hm = new HashMap(); String sPerson = "The physical person"; hm.put("Official name", sPerson); hm.put("Nick name", sPerson); hm.put("Fake name", sPerson); System.out.println(hm); } } //output //{Official name=The physical person, Fake name=The physical person, Nick name=The physical person}
Q. Is TreeSet ordered? What is the difference between sorted and ordered? A: Yes! TreeSet is an implementation of the SortedSet interface. It is sorted. Sorted is ordered, and ordered is not necessary sorted. This is more philosophical point of view than Java specific. As a former/current physicist, entropy decreases when things are ordered or sorted. Sorted is a specialization of ordered. Ordered is a generalization, which should include a specific order - sorted. They are not independent of each other.From my freshman computer science course (Even when I was freshman, I did not have any computer science courses. ), when you insert an item into an binary search tree, it will be insert somewhere to make the tree still ordered by certain criteria. The binary search tree is ordered by any sense to me.
Q. What does it mean that remove() method in Collection interface is optional? We don't need to implement the method? A: optional: not compulsory From http://m-w.com/cgi-bin/dictionary Yes, you do need to implement the remove() method, otherwise, the implementation class need to be abstract. When you need the functionality, then you implement it. Otherwise, you actually can make it not usable (see example below), because it is optional. Another question, I could do the same to any other methods, why this is announced as optional? My guess is since this is documented as optional, then if it is not supported, there will be no surprises to the user, which is an important principle in software engineering. See the following code, the remove() method here is actually not supported as the exception name indicated: public void remove() { throw new UnsupportedOperationException(); }
Q. When should I use Arrays and when should I use collection classes? A: •
• •
Using array whenever you can. It will not only save you time, but also save you space/memory too. What a deal? When you have fixed sized collection of objects, or the size is predictable, and you are not going to insert, remove elements from the middle/front. Using ArrayList, Map, Set, etc. when you must. Try to avoid Using Vector, HashTable since they are synchronized and very slow:
• Q. What are the differences between ArrayList and Vector? What should I use? A: HashMap and ArrayList have basically replaced their synchronized brother HashTable and Vector. HashTable and Vector are about 3 times slower. If you think it is safer to use HashTable and Vector, think twice, that synchronization only on the atomic operation based, they usually give you a fake safe feeling, which might make your code less safe. Use HashMap and ArrayList unless your boss commands you otherwise. Or what you are doing is extremely security sensitive, the security should be obtained at any price. In that case, I still don't think you will go to sleep soundly because you are using Vector or HashTable.
Q. I can print my HashTable and obtain a string. Can I reverse the process? A: All Java Object has a toString() method. They are not supposed to be reversable unless you design your own.
Other Util Classes Q. How to do arithmetic in Calendar class? A: Here is an example; we try to add 5 days to 02/28/2001: import java.util.*; import java.text.SimpleDateFormat; public class G { public static void main (String [] args) { SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy"); Date date = null; try { date = df.parse("02/28/2001"); System.out.println(date); } catch (Exception e) { } Calendar cal= Calendar.getInstance(); cal.setTime(date); cal.add(Calendar.DATE, 5); System.out.println(cal.getTime()); } } // output // Wed Feb 28 00:00:00 CST 2001 // Mon Mar 05 00:00:00 CST 2001
Q. How to calcucate the date difference between 09-01-2002 23:59:59 and 09-022002 00:00:01?? A: Interesting question!!! The real time difference is 2 seconds. However, the date difference is one. The answer will also be different when you are in a different time zone. The different dates in London, UK does not mean different dates in Beijing, China. How do we get the right answer?Here we are! A full functional tested answer can be found at here . Enjoy!
Regular expressions
Q. How to use Pattern.split() method not to get empty strings? My input string is "This is . a tough.sale. scenario." I want to get rid of spaces and periods to get the tokens. A: Simple, here is the code: import java.util.regex.Pattern; public class P { public static void main(String[] args) { String input = "This is . a tough.sale. scenario."; String pattern = "[\\s\\.]+"; Pattern patt = Pattern.compile(pattern); String[] result = patt.split(input); for (int i = 0; i < result.length; i++) { System.out.println("\""+result[i]+"\""); } } }
Q. How to use String.split() method, I want to use '|' as separator, it does not work. A: Attention, Please! In this method, parameter is a regular expression, not a delimiter list. public String[] split(String regex);
Then you will know why you put String "|" as regex will definitely not work. Since '|' in regex means 'or'. Then what will work? See this following code: public class S { public static void main(String[] args) { String str = "boo|and|asd||foo"; // If empty string is OK, then take the plus sign (+) off String regex = "[\\|]+"; String[] toks = str.split(regex); for(int i = 0; i < toks.length; i++) { System.out.println(toks[i]); } } }
Q. How to use regular expression to pickup all numbers from an arbitrary String? A: Sample code import java.util.regex.*; public class Test { public static void main(String[] args) { String s = "whatever 45 -- ad8fadds9djjj 12342d2s"; Pattern p=Pattern.compile("\\d+"); Matcher m=p.matcher(s); StringBuffer sb=new StringBuffer(); while(m.find()) { sb.append(m.group());
} System.out.print(sb); } }
Multi Threading Basics Q. Why cannot we synchronized public object to lock the memory for avoiding multi-thread access? A: synchronized has nothing to do with locking memory, but controlling access to a block of code, which may access and change the memory/database/file contents, the integrity of which might be compromized by multi-thread simultaneous access or changes. Here, I intentionally missed how synchronized works, uses what kind of working mechanism. Read other part of the FAQ for that, please. public/private/protected access modifiers have no relationship with synchronized, even they share a word "access". They are for encapsulation, in other words, information sharing or hiding. Like your family, you may want certain information to be public, some to be known only by your relatives or close friends, some to be kept only to your family members. Some might be kept to yourself only, hoho, a secret. They are different concepts and serve different purposes. Q. I found this statement about thread in some tutorial on Internet, Is it true? The main thread must be the last thread to finish execution. When the main thread stops, the program terminates. A: Absolutely wrong! The correct one: JVM creates one user thread for running a program. This thread is called main thread. The main method of the class is called from the main thread. It dies when the main method ends. If other user threads have been spawned from the main thread, program keeps running even if main thread dies. Basically a program runs until all the user threads (non-daemon threads) are dead.This is actually most GUI (Swing) application works. The main thread creates a thread for the GUI frame work; then it finishes and becomes dead. The GUI will still running until the user closes it or something else kills it. Microsoft GUI application basically works the same way. A simple sample code (even not GUI) here! class T extends Thread { boolean runflag = true; public T(String name){ super(name); } public void run() { int i = 0;
while (runflag) { System.out.println(getName() + ": " + i++); try { sleep((int)(700*Math.random())); } catch (InterruptedException e) { } } System.out.println(getName() + " is stopping."); } void setRunFlagFalse() { runflag = false; } public static void main(String args[]) { T t1=new T("t1"); T t2=new T("t2"); T t3=new T("t3"); t1.setDaemon(true); t1.start(); t2.start(); t3.start(); try { // let three threads run Thread.sleep(600); } catch (InterruptedException e) { } // t2 will stop t2.setRunFlagFalse(); System.out.println("t3 will not stop after main stop"); System.out.println("t1 will stop after all user threads stopped"); System.out.println("Use ^C to stop everything, when you had enough"); System.out.println("main thread is stopping."); } }
Q. What is the basic concept of synchronized keyword, is it responsible to our data integrity? A: The key concept of synchronized keyword is locking the code to prevent other thread to access the critical code when one thread is processing it. You need acquire the monitor/lock from an object to lock it, and one object only has one lock/monitor. That is why when one thread acquired the lock/monitor, other threads have to wait. Why you need to lock the code? Mostly you need to keep the integrity of your data, and which is
very application specific. The locking mechanism actually knows nothing about it. It is NOT responsible for your data integrity at all. It is you, the application programmer, who is responsible for it. For example, if you want to keep the integrity of your client's bank account balance, you must synchronize all methods, which have access to and can change the balance. If you leave a loophole there, you probably will be fired by your boss, not Dr. Gosling or someone else who designed the locking mechanism. I just want to scare you... However, when you are synchronizing the code, which has access to the client's account balance, you probably still can change his/her email address or list of hobbies for advertisement purposes. Of course, if you are really serious on that stuff too, you might want to synchronize the code, which has access those data independently.Programmers need to practice some examples to really understand it. Some times, I still get confused. Concurrent programming is not an easy subject. It is not Java specific either. Race condition, dead lock, critical section, semaphore, monitor, thread scheduling, thread pooling, etc. etc...I'm still in the learning process... How about we learn together. Q. Why we should call Thread.start() to start a Thread? I called the run() method, no error or exception at all, why? A: When you call Thread start() method, JVM will create a new Thread, then call run() method of the new Thread. The new Thread will run concurrently with the original calling Thread.If you directly call the run() method, the Thread will act as a normal Java object. No new Thread will be created. The code will run sequentially. Try the following code to see the difference, and get a feeling of concurrency. // MyRun.java public class MyRun implements Runnable { public static void main(String argv[]) MyRun r = new MyRun(); Thread t = new Thread(r);
{
// t is still running after Main finished t.start(); // No new thread created, Main finishes after run() returns // t.run(); try { // See concurrency if you call t.start() // See sequential if you call t.run() for (int i = 0; i < 5; i++) { Thread.sleep(10); System.out.println("in Main: " + i); } } catch (InterruptedException e) { System.out.println(e); } System.out.println("Main thread finished..."); } public void run(){ try {
for (int i = 0; i < 5; i++) { Thread.sleep(20); System.out.println("in Run: " + i); } } catch (InterruptedException e) { System.out.println(e); } System.out.println("Run method finished..."); } }
Q. Thread t = null; t.yield(), is this legal? If it is, what is the effect of the statement? A: Yes, but it is bad coding style. It is equivalent to Thread.yield(), which will cause the current thread to yield, and becomes ready state. The purpose of yield() is let other Thread has a chance to execute.Since yield() is a static method of Thread class, the only concern to compile is the type, that is why t.yield(); and Thread.yield(); are exact the same. However, it is confusing human beings. It is bad, but legal practice. It is good for you to really understand what is static method. Q. In some mocking exam, after the definition of Thread t = new Thread(); then both yield(); and t.yield(); are marked as alternative answers for causing the current running thread to pause. Is it generally correct? A: No! It is generally incorrect. In some special situation, it will compile and work, however, it should still be considered as bad coding practice. The special case is: when yield(); is called inside a Thread class ( in a main, or other method ).You should use Thread.yield() instead to accomplish the task. For more discussion, read the question above.The following example shows you the general case, if you call yield(); it will not compile. // ThreadTest.java import java.io.*; class MyThread extends Thread { public void run(){ for (int i=0; i 2 3.5 --> 4
Is it inaccurate? Yes, that is the purpose of round() function. You want it accurate, then don't use round. To the top Q. How to generate random number in a range? A: Simple int getRandom(int min, int max) { return min + (int)(Math.random() * (max - min + 1)); }
To the top
Expression & Java operators Q. What is the differences between == operator and equals() method? A: 1. No equals() method for primitive types. Of course, primitive type wrapper classes (e.g. Integer class) do. 2. == operator compares the values of primitive types. 3. == operator compares the reference (values) of Objects. 4. Unlike C++, Java does not allow operator overwriting. Which means two identical objects A and B, A==B will never happen.
5. Object.equals() will behave exact the same as ==, unless it is overridden by the subclass. 6. More equals / == examples here, TestEqual.java 7. Warning: Don't try this at work! To the top Q. What is the difference of --b and - - b? Why does the following code behave strangely? byte b = 2; b = -- b; //Compiles ok and prints 1 b = - - b ; //Compiler error because explicit cast needed to convert int to byte.
A: 1. Spaces are significant here. No spaces allowed in the follow operators: --, ++, +=, -=, /=, *=, %=, etc. 2. -- is decrement operator, in -- b or --b, the operand keeps its original type. It is byte in your case. 3. - - b is equivalent to -(-b), like most integer type operators, it is default to int. 4. Assign an int to byte; type cast is required. To the top Q. What is the difference of x=x+3 and x+=3? Why one needs type cast and the other does not? char x = 'a'; x += 3; // ok x = x + 3; // compile time error
A: Because x += 3; is equivalent to x = (char)(x+3); while x + 3 is default to int operation, assign an int to char must cast.Copied from JLS 15.26.2 "A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once. Note that the implied cast to type T may be either an identity conversion (?.1.1) or a narrowing primitive conversion (?.1.3)." To the top Q. What is expression in Java or other computer languages? A: Expression must have a value! It can be assigned to a variable with corresponding type. Expression examples: (3 + 4) int expression with value of 7. int x = (3 + 4); //OK (1 != 2) boolean expression with value of true. boolean b = (1 != 2); //OK ("girl") String expression with value of "girl".
String s = ("girl"); //OK(math.max(2.3, 4.9)) double expression with value of 4.9. double d = (math.max(2.3, 4.9));//OK(if (x > y){ return x;} else {return y;}) Invalid expression with no value! It is because if-statement does not return any value. Can you assign it to anything? NONE!! To the top Q. What is logical operator short-circuiting? A: This is a basic concept in computer sciences, not limited to Java. You'd better understand it.Two boolean expressions A, B, if A is false, you know A and B must be false, you don't need to evaluate B to know the answer.If the computer language allows and operator short-circuiting, B will not be evaluated. If B happens to be a long and complicated calculation, and produces a lot of side effects, even throw exceptions, those will not happen when A evaluates false.However, if the computer language does not allow and operator short-circuiting, B will be always evaluated, no matter what is the value of A.c language is always short-circuiting. Standard Pascal does not allow short-circuiting. However, Turbo Pascal does.Java just tries to make your life more miserable, it makes && short-circuiting, but & not short-circuiting.I used && and & to illustrate the concepts, you need to figure out how || or | works in Java. This is your homework assignment. In addition, you need to know: •
•
In Java, | & are overloaded, they are bitwise operators as well as non-shortcircuiting logic operators, which depends on the parameters passed to them. Operator overloading is not new, it is used since FORTRAN time. Here is the full compilable, runnable, testable code for you to play with.
public class ShortCircuiting { public static boolean bfunction() { System.out.println("***Inside bfunction, " + "we have a side effect!***"); return true; } public static void main(String[] args) { System.out.println("======================="); if (false && bfunction()) { System.out.println("This will never be printed out"); } else { System.out.println("&& logic operator used, " + "you will not see the side effect."); } System.out.println("======================="); if (false & bfunction()) { System.out.println("This will never be printed out"); } else { System.out.println("& logic operator used, " + "you see the above side effect."); }
System.out.println("======================="); System.out.println("You should understand the " + "concepts of short-circuiting and side effect."); System.out.println("Now, it is your turn to try the || or |."); System.out.println("======================="); } } //output: //======================= //&& logic operator used, you will not see the side effect. //======================= //***Inside bfunction, we have a side effect!*** //& logic operator used, you see the above side effect. //======================= //You should understand the concepts of short-circuiting and side effect. //Now, it is your turn to try the || or |. //=======================
To the top Q. When (1) x and y refer to two different object, or (2) x.equals(y) returns false, is (x.hashCode() == y.hashCode()) always return false in these two situation. Why? A: No, not necessarily. The opposite is true. When (3) x and y refer to the same object, or (4) x.equals(y) returns true, then (x.hashCode() == y.hashCode()) always returns true.Read JDK DOC here, it helps for sure! http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode() To the top
Arrays in Java Q. What are arrays in Java? Do all array elements be initialized to default value? A: Arrays are objects in Java. Array elements are just member variables of the class, and they are initialized to default value as any other class of objects.MyObject[] myobjarray; There is no array here, only an array reference type variable called myobjarray. If it is a field in another class, myobjarray will be initialized to null. If it is in a method, it will not be initialised. No exceptions here!!! MyObject[] myobjarray = new MyObject[5]; You are initializing myobjarray by constructing a MyObject[5] array, inside the new object instance of the MyObject[5] array, all fields will be initialized to default values, which are myobjarray[0] = null, myobjarray[1] = null, ... and the length field would be initialized to 5. No exceptions here either!!!The only difference is that array classes do not have an known name. If you are really interested to know the class name of various arrays, you can see them here. It actually prints out some odd class names of arrays: TestRange.javaSee the bottom of the code. To the top Q. How to create an array with actually 3 HashMaps in it?
A: See the following code snippets HashMap[] maps = new HashMap[3]; for (int i=0; idoSomething(); } // output: // doSomething in A // doSomething in B //-----------// A.java public class A { public A() { doSomething(); } public void doSomething() { System.out.println("doSomething in A"); } public static void main(String[] args) { B b = new B(); b.doSomething(); } } class B extends A { public void doSomething() { System.out.println("doSomething in B"); } } // output: // doSomething in B // doSomething in B
A: We all know, C++ is default to static binding, if virtual, than dynamic binding apply. However, the doSomething() call in A constructor is not dynamically bound even it is virtual. Java is default to dynamic binding, unless you specify the method as static. The doSomething() call in A constructor is dynamically bound.
The reason is C++ is using vtable to load the class, but Java is using ClassLoader to load the class. Of course, Java could have designed to not allow dynamic binding in constructor, since it is generally considered not good practice of OO. Try to avoid calling overridable method in constructor. It is considerred a good coding practice in some opinions. However, there is no universal agreement on this issue. You are most likely to do what your archtects or boss asking you to do. Just remember the facts will benifit you, since they are both good interview questions. To the top Q. There are a lot of syntax similarities between Java and C++, what are the fundamental differences? A: Read some answers from the founding father of the great C++ programming language Dr. Bjarne Stroustrup . You will be suprised how much you can learn from there! Search the word Java. It will be great experience for you no matter you knew C++ or not. We need pay respect to history. Even C++ is not history yet, it is still very much alive as Java. Q. How to define C-like global variable in Java? A: The basic rule is not to use global variables unless absolutely necessary. This rule applies even you are writing C or Pascal code. When it is really really absolutely necessary(??), make a class called Global and all members public static, no setters, no getters. Make them look very obvious unmistakenly global. Then it is a duty of every programmer to maintain the integrity of Global class. public class Global { public static int g_num; public static char[] g_charray; public static byte[] g_bytearray; // more here }
Please, please don't use this technic unless absolutely necessary. Use it, don't abuse it!!! To the top Q. What is the difference of function and method? A: They are basically the same thing. subroutine, procedure, function, method, they are basically the same thing, used in different languages, in computer science history. • • • • •
Method is usually used in OO languages, such as Java. Function is used in c/c++/Pascal. Procedure is used In Pascal, funtion returns a value, procedure does not. Subroutine is used in FORTRAN/BASIC. ... I just give you some examples, not a complete list.
What is the common use for them? Make code reusable. Subroutine is a big invention in FORTRAN language! We don't need to write the same piece of code again and again and again! It seems a simple commonplace to you and me. However, it was a great invention in computer science history! To the top
Miscellaneous Q.When I run the code with "java test *", why it has a number of parameters as many as the number of files under the directory? class test{ public static void main(String args[]){ for (int i = 0; i < args.length; i++) { System.out.println("Para"+i+":"+args[i]); } if (args.length
View more...
Comments