Online Java Programming Test - Java Programming Test - Random
- This is a FREE online test. Beware of scammers who ask for money to attend this test.
- Total number of questions: 20.
- Time allotted: 30 minutes.
- Each question carries 1 mark; there are no negative marks.
- DO NOT refresh the page.
- All the best!
Marks : 2/20
Test Review : View answers and explanation for this test.
- float f1 = -343;
- float f2 = 3.14;
- float f3 = 0x12345;
- float f4 = 42e7;
- float f5 = 2001.0D;
- float f6 = 2.81F;
(1) and (3) are integer literals (32 bits), and integers can be legally assigned to floats (also 32 bits). (6) is correct because (F) is appended to the literal, declaring it as a float rather than a double (the default for floating point literals).
(2), (4),and (5) are all doubles.
interface is a valid keyword.
Option B is wrong because although "String" is a class type in Java, "string" is not a keyword.
Option C is wrong because "Float" is a class type. The keyword for the Java primitive is float.
Option D is wrong because "unsigned" is a keyword in C/C++ but not in Java.
- private int getArea();
- public float getVol(float x);
- public void main(String [] args);
- public static void main(String [] args);
- boolean setFlag(Boolean [] test);
(2), (3), and (5). These are all valid interface method signatures.
(1), is incorrect because an interface method must be public; if it is not explicitly declared public it will be made public implicitly. (4) is incorrect because interface methods cannot be static.
class Super
{
public Integer getLength()
{
return new Integer(4);
}
}
public class Sub extends Super
{
public Long getLength()
{
return new Long(5);
}
public static void main(String[] args)
{
Super sooper = new Super();
Sub sub = new Sub();
System.out.println(
sooper.getLength().toString() + "," + sub.getLength().toString() );
}
}
Option D is correct, compilation fails - The return type of getLength( ) in the super class is an object of reference type Integer and the return type in the sub class is an object of reference type Long. In other words, it is not an override because of the change in the return type and it is also not an overload because the argument list has not changed.
class Two
{
byte x;
}
class PassO
{
public static void main(String [] args)
{
PassO p = new PassO();
p.start();
}
void start()
{
Two t = new Two();
System.out.print(t.x + " ");
Two t2 = fix(t);
System.out.println(t.x + " " + t2.x);
}
Two fix(Two tt)
{
tt.x = 42;
return tt;
}
}
In the fix() method, the reference variable tt refers to the same object (class Two) as the t reference variable. Updating tt.x in the fix() method updates t.x (they are one in the same object). Remember also that the instance variable x in the Two class is initialized to 0.
public class Test
{
public static void leftshift(int i, int j)
{
i <<= j;
}
public static void main(String args[])
{
int i = 4, j = 2;
leftshift(i, j);
System.out.println(i);
}
}
Java only ever passes arguments to a method by value (i.e. a copy of the variable) and never by reference. Therefore the value of the variable i remains unchanged in the main method.
If you are clever you will spot that 16 is 4 multiplied by 2 twice, (4 * 2 * 2) = 16. If you had 16 left shifted by three bits then 16 * 2 * 2 * 2 = 128. If you had 128 right shifted by 2 bits then 128 / 2 / 2 = 32. Keeping these points in mind, you don't have to go converting to binary to do the left and right bit shifts.
class PassA
{
public static void main(String [] args)
{
PassA p = new PassA();
p.start();
}
void start()
{
long [] a1 = {3,4,5};
long [] a2 = fix(a1);
System.out.print(a1[0] + a1[1] + a1[2] + " ");
System.out.println(a2[0] + a2[1] + a2[2]);
}
long [] fix(long [] a3)
{
a3[1] = 7;
return a3;
}
}
Output: 15 15
The reference variables a1 and a3 refer to the same long array object. When the [1] element is updated in the fix() method, it is updating the array referred to by a1. The reference variable a2 refers to the same array object.
So Output: 3+7+5+" "3+7+5
Output: 15 15 Because Numeric values will be added
public class If1
{
static boolean b;
public static void main(String [] args)
{
short hand = 42;
if ( hand < 50 && !b ) /* Line 7 */
hand++;
if ( hand > 50 ); /* Line 9 */
else if ( hand > 40 )
{
hand += 7;
hand++;
}
else
--hand;
System.out.println(hand);
}
}
In Java, boolean instance variables are initialized to false, so the if test on line 7 is true and hand is incremented. Line 9 is legal syntax, a do nothing statement. The else-if is true so hand has 7 added to it and is then incremented.
for (int i = 0; i < 4; i += 2)
{
System.out.print(i + " ");
}
System.out.println(i); /* Line 5 */
Compilation fails on the line 5 - System.out.println(i); as the variable i has only been declared within the for loop. It is not a recognised variable outside the code block of loop.
public class Switch2
{
final static short x = 2;
public static int y = 0;
public static void main(String [] args)
{
for (int z=0; z < 3; z++)
{
switch (z)
{
case y: System.out.print("0 "); /* Line 11 */
case x-1: System.out.print("1 "); /* Line 12 */
case x: System.out.print("2 "); /* Line 13 */
}
}
}
}
Case expressions must be constant expressions. Since x is marked final, lines 12 and 13 are legal; however y is not a final so the compiler will fail at line 11.
public class X
{
public static void main(String [] args)
{
try
{
badMethod();
System.out.print("A");
}
catch (RuntimeException ex) /* Line 10 */
{
System.out.print("B");
}
catch (Exception ex1)
{
System.out.print("C");
}
finally
{
System.out.print("D");
}
System.out.print("E");
}
public static void badMethod()
{
throw new RuntimeException();
}
}
A Run time exception is thrown and caught in the catch statement on line 10. All the code after the finally statement is run because the exception has been caught.
java.lang.StringBuffer is the only class in the list that uses the default methods provided by class Object.
public class Foo
{
Foo()
{
System.out.print("foo");
}
class Bar
{
Bar()
{
System.out.print("bar");
}
public void go()
{
System.out.print("hi");
}
} /* class Bar ends */
public static void main (String [] args)
{
Foo f = new Foo();
f.makeBar();
}
void makeBar()
{
(new Bar() {}).go();
}
}/* class Foo ends */
Option C is correct because first the Foo instance is created, which means the Foo constructor runs and prints "foo". Next, the makeBar() method is invoked which creates a Bar, which means the Bar constructor runs and prints "bar", and finally the go() method is invoked on the new Bar instance, which means the go() method prints "hi".
Option A is correct. wait() causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.
Option B is wrong. notify() - wakes up a single thread that is waiting on this object's monitor.
Option C is wrong. notifyAll() - wakes up all threads that are waiting on this object's monitor.
Option D is wrong. Typically, releasing a lock means the thread holding the lock (in other words, the thread currently in the synchronized method) exits the synchronized method. At that point, the lock is free until some other thread enters a synchronized method on that object. Does entering/exiting synchronized code mean that the thread execution stops? Not necessarily because the thread can still run code that is not synchronized. I think the word directly in the question gives us a clue. Exiting synchronized code does not directly stop the execution of a thread.
public class SyncTest
{
public static void main (String [] args)
{
Thread t = new Thread()
{
Foo f = new Foo();
public void run()
{
f.increase(20);
}
};
t.start();
}
}
class Foo
{
private int data = 23;
public void increase(int amt)
{
int x = data;
data = x + amt;
}
}
and assuming that data must be protected from corruption, what—if anything—can you add to the preceding code to ensure the integrity of data?Option D is correct because synchronizing the code that actually does the increase will protect the code from being accessed by more than one thread at a time.
Option A is incorrect because synchronizing the run() method would stop other threads from running the run() method (a bad idea) but still would not prevent other threads with other runnables from accessing the increase() method.
Option B is incorrect for virtually the same reason as A—synchronizing the code that calls the increase() method does not prevent other code from calling the increase() method.
class Bar { }
class Test
{
Bar doBar()
{
Bar b = new Bar(); /* Line 6 */
return b; /* Line 7 */
}
public static void main (String args[])
{
Test t = new Test(); /* Line 11 */
Bar newBar = t.doBar(); /* Line 12 */
System.out.println("newBar");
newBar = new Bar(); /* Line 14 */
System.out.println("finishing"); /* Line 15 */
}
}
At what point is the Bar object, created on line 6, eligible for garbage collection?Option B is correct. All references to the Bar object created on line 6 are destroyed when a new reference to a new Bar object is assigned to the variable newBar on line 14. Therefore the Bar object, created on line 6, is eligible for garbage collection after line 14.
Option A is wrong. This actually protects the object from garbage collection.
Option C is wrong. Because the reference in the doBar() method is returned on line 7 and is stored in newBar on line 12. This preserver the object created on line 6.
Option D is wrong. Not applicable because the object is eligible for garbage collection after line 14.
This is a great way to think about when objects can be garbage collected.
Option A and B assume guarantees that the garbage collector never makes.
Option D is wrong because of the now famous islands of isolation scenario.
public class Test
{
public void foo()
{
assert false; /* Line 5 */
assert false; /* Line 6 */
}
public void bar()
{
while(true)
{
assert false; /* Line 12 */
}
assert false; /* Line 14 */
}
}
What causes compilation to fail?Option D is correct. Compilation fails because of an unreachable statement at line 14. It is a compile-time error if a statement cannot be executed because it is unreachable. The question is now, why is line 20 unreachable? If it is because of the assert then surely line 6 would also be unreachable. The answer must be something other than assert.
Examine the following:
A while statement can complete normally if and only if at least one of the following is true:
- The while statement is reachable and the condition expression is not a constant expression with value true.
-There is a reachable break statement that exits the while statement.
The while statement at line 11 is infinite and there is no break statement therefore line 14 is unreachable. You can test this with the following code:
public class Test80
{
public void foo()
{
assert false;
assert false;
}
public void bar()
{
while(true)
{
assert false;
break;
}
assert false;
}
}
public class Test2
{
public static int x;
public static int foo(int y)
{
return y * 2;
}
public static void main(String [] args)
{
int z = 5;
assert z > 0; /* Line 11 */
assert z > 2: foo(z); /* Line 12 */
if ( z < 7 )
assert z > 4; /* Line 14 */
switch (z)
{
case 4: System.out.println("4 ");
case 5: System.out.println("5 ");
default: assert z < 10;
}
if ( z < 10 )
assert z > 4: z++; /* Line 22 */
System.out.println(z);
}
}
which line is an example of an inappropriate use of assertions?Assert statements should not cause side effects. Line 22 changes the value of z if the assert statement is false.
Option A is fine; a second expression in an assert statement is not required.
Option B is fine because it is perfectly acceptable to call a method with the second expression of an assert statement.
Option C is fine because it is proper to call an assert statement conditionally.
public class Myfile
{
public static void main (String[] args)
{
String biz = args[1];
String baz = args[2];
String rip = args[3];
System.out.println("Arg is " + rip);
}
}
Select how you would start the program to cause it to print: Arg is 2Arguments start at array element 0 so the fourth arguement must be 2 to produce the correct output.