The Source for Java Technology Collaboration
User: Password:



Petar Tahchiev

Petar Tahchiev's Blog

A Few Questions To Test Yourself

Posted by paranoiabla on February 01, 2007 at 02:27 AM | Comments (4)

Hello everybody,

recently I was sent a few interesting questions by my friend Angel Evrov, but being busy enough I had no time to look at them. Anyway, I finally found a few spare hours, and the problems turned out to be very interesting, so here they come.
Question I: Consider the following Java class:

public class MagicOutput {

    public static void main(final String argv[]) {

        System.out.println("Hello, World!");

    }

}
While preserving both method main signature (name, number and type of parameters, return type) and implementation (body of method), make this program to output to standard console message "Hello, Java Guru!" Again, you may not alter a single character within the method main!!! The resulted class must be executable with JRE 1.4; you may not use classes besides public API of JDK 1.4

Solution I:
The solution I immediately got was the one that is most common. As we know static blocks are executed before the main method, so the only thing we have to make sure is that we insert a static block in our class and also ensure that we never execute the main method. Here is the solution:
public class MyDraft {

	static {
		System.out.println("Hello World JavaGuru!");
		System.exit(0);
	}

	public static void main(String[] args) {
		System.out.println("Hello World!");	
	}
}
Solution II:
This is the solution of Radoslav Nikolov, who I would like to thank for pointing it to me:
public class MagicOutput {

    static String HELLO_WORLD = "Hello, World!";

    static char[] HELLO_GURU_CHARS = "Hello, Java Guru!".toCharArray();

 

    static {

        try {

            Field f;

 

            f = String.class.getDeclaredField("value");

            f.setAccessible(true);

            f.set(HELLO_WORLD, HELLO_GURU_CHARS);

 

            f = String.class.getDeclaredField("count");

            f.setAccessible(true);

            f.setInt(HELLO_WORLD, HELLO_GURU_CHARS.length);

 

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

 

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

        System.out.println("Hello, World!");

    }

}
The idea here is basically this: we again use the static block to start the solution before the jvm executes the main method, but this time we declare the "real" string and the "fake" string as instance variables of the class. Then we use a simple reflection trick to change the value of the "real" string with the "fake" one, and later when executing the main method the changed string value is displayed. Simple and clean :-).


Question II:
Given:
public String makinStrings() {

	String s = "Fred";

	s = s + "47";

	s = s.substring(2, 5);

	s = s.toUpperCase();

	return s.toString();
}
How many String objects will be created when this method is invoked?

Answer:

One of the most interesting things is that the real ansewr is 3. Because the string objects that correspond to values of "Fred" and "47" already exist in the pool and four of this methods return new objects(the .toString() method does not produce a new object) so i think that there are 2 in the pool and 3 in the heap.

Question III: Consider the following code:
public static int testMethod() {
	for(;;) {
	}
}
Does the code compile?
Answer: Interesting enough, but the code compiles. Now a next question arises: "Why does the code copmpile?". Is this a bug in the java compiler? Or maybe a feature, considering the fact that the for cycle never ends? And if it is a feature, shouldn't it mark a warning? I would like to hear your comments. What do you think?

Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • In question II you say 3 (correct) but "all of this methods return new objects" (incorrect).

    s+"47" creates one, substring() creates one and toUpperCase() creates one. toString() does not... it just returns this if it's already a string.

    Question III: I think that a warning could be thrown out by the compiler (with -Xlint), but otherwise it's ok.

    A good IDE will warn you though, eg IntelliJ IDEA tells you that the "for statement cannot complete without throwing an exception."

    Posted by: goron on February 01, 2007 at 04:30 AM

  • Question I: There are stranger ways.

    Question III: You can't have warnings for everything.

    Posted by: tackline on February 01, 2007 at 02:32 PM

  • here is another solution (solution provider Lakshmi Narasimhan V):

    public class Dummy3 {
    static class System {
    static class out {
    public static void println(String str) {
    java.lang.System.out.println("Hello, Java Guru!");
    }
    }
    }

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

    System.out.println("Hello, World!");
    }
    }

    Posted by: selvarajk on June 21, 2007 at 07:44 AM

  • interesting question, but i do not agree on question II and III. Digital Photo Frame

    Posted by: lengqing on June 05, 2008 at 12:38 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds