Mock Exam - 1
public E getElement() { return element;
Question 1 :
}
With generics the compiler has more information about the types of the objects, so explicit casts don't have to be used and the compiler can produce type safe code.
} We will store fruits in the baskets:
What implications have the generics for the runtime performance of the program which uses them?
class Fruit {
a)With the generics the compiler can optimize the code for used types. This and the omission of the casts are the reasons why the code compiled with the generics is quicker than the one compiled without.
class Apple extends Fruit {
b)The usage of generics has no implications for the runtime performance of the compiled programs.
class Orange extends Fruit {
c)The improved flexibility and type safety means that the compiler has to generate concrete implementation from the generic template for each used type. This means that applications start a bit slower.
}
}
} What would Java 1.5 do with the following source code? Basket
basket = new Basket(); // 1
Question 2 :
basket.setElement(new Apple()); // 2
As an example for a generic class we will use a very simple container. A Basket can contain only one element. Here the source code:
Apple apple = basket.getElement(); // 3 a)The source code is OK. Neither the compiler will complain, nor an exception during the runtime will be thrown. b)Compile error in the line 2.
public class Basket<E> {
c)Compile error in the line 3.
private E element; public void setElement(E x) { element = x; }
Question 3 : Let's stay with our baskets. What do you think about the following source code?
Basket basket = new Basket();
Basket b = new Basket();
basket.setElement(new Apple());
b.setElement(new Apple());
Orange orange = (Orange) basket.getElement();
Apple apple = (Apple) b.getElement(); // Source C
a)e source code is OK. Neither the compiler will complain, nor an exception during the runtime will be thrown b)mpile error in the line 2.
Basket b1 = new Basket(); b1.setElement(new Apple()); Apple apple = (Apple) b1.getElement();
c)mpile error in the line 3.
Which of the following statements are true? a)Source A cannot be compiled
d)ClassCastException will be thrown in the line 3.
b)Source B will be compiled with warning(s).
Question 4 :
c)No exception will be thrown during the runtime. Source C will be compiled with warning(s). A ClassCastException exception will be thrown during the runtime
Which ones of the following lines can be compiled without an error? a)Basket b = new Basket(); b)Basket b1 = new Basket(); c)Basket b2 = new Basket(); d)Basket<Apple> b3 = new Basket(); e)Basket b4 = new Basket<Apple>(); f)Basket> b5 = new Basket<Apple>(); g)Basket<Apple> b6 = new Basket>();
Question 6 : And what aobout this one? Basket b = new Basket(); // 1 Basket<Apple> bA = b; // 2 Basket bO = b; // 3
Question 5 : Let's have a look at the typeless baskets and the ones where the type is an unbounded wildcards. // Source A Basket> b5 = new Basket<Apple>(); b5.setElement(new Apple());
bA.setElement(new Apple()); // 4 Orange orange = bO.getElement(); // 5 a)The lines 2 and 3 will cause a compile error. b)The line 4 will cause a compile error. c)The line 5 will cause a compile error because a cast is missing. d)The source code will be compiled with warning(s). During the runtime a ClassCastException will be thrown in the line 5. e)The soure code will be compiled with warning(s). No exception will be thrown during the runtime.
Apple apple = (Apple) b5.getElement(); // Source B
Question 7 :
In our rich class hierarchy the class Apple has following subclasses: class GoldenDelicious extends Apple {}
g)public static boolean isRipeInBasket(Basket Basket)
class Jonagold extends Apple {} Our fruit processing application contains an utility class which can decide, whether an apple is ripe: class FruitHelper { public static boolean isRipe(Apple apple) { ... } }
Question 8 : Now we want to implement a method which inserts only ripe apples into the basket. Here the method's body: {background:#FFFFFE; border:none; padding:0in; } }
In the class FruitHelper we want to implement a method which can look into any basket which can contain apples only and decide, whether the apple in the basket is ripe of not. Here the body of the method: { Apple apple = basket.getElement(); // 1 return isRipe(apple); // 2 }
Which of these signatures should we use? a)public static void insertRipe(Apple apple, Basket<Apple> basket) b)public static void insertRipe(Apple apple, Basket extends Apple> basket)
What should the signature of the method look like:
c)public static void insertRipe(Apple apple, Basket super Apple> basket)
a)public static boolean isRipeInBasket(Basket basket)
d)public static void insertRipe(A apple, Basket super A> basket)
b)public static boolean isRipeInBasket(Basket<Apple> basket
e)public static void insertRipe(A apple, Basket extends A> basket)
c)public static boolean isRipeInBasket(Basket> basket) d)public static boolean isRipeInBasket(Basket extends Apple> basket)
Question 9 :
e)public static boolean isRipeInBasket(Basket basket)
We could acquire some expertise in the orangeology and now we can decide whether an orange is ripe or not - and this in pure Java. Now we want to extend the class FruitHelper.
f)public static boolean isRipeInBasket(Basket basket)
Here is our updated source code :
class FruitHelper {background:#FFFFFE; border:none; padding:0in; }
public static boolean isRipe(Orange orange) {background:#FFFFFE; border:none; padding:0in; }
public static boolean isRipe(Orange orange) {background:#FFFFFE; border:none; padding:0in;
public static
}
void insertRipe(A a, Basket super A> b) {
basket) {
public static boolean isRipeInBasket(Basket extends Apple>
if (isRipe(a)) { b.setElement(a);background:#FFFFFE;
Apple apple = basket.getElement();
border:none; padding:0in;
return isRipe(apple);background:#FFFFFE; border:none;
}
padding:0in;
}
}
public static
public static boolean isRipeInBasket(Basket extends Orange>
void insertRipe(G g, Basket super G> b)
basket) {
{
Orange orange = basket.getElement(); return isRipe(orange);background:#FFFFFE; border:none; padding:0in; }
if (isRipe(g)) { border:none; padding:0in;
b.setElement(g);background:#FFFFFE;
}
}
}
Ist this source code OK?
}
a)Yes. The source code is OK.
a)Yes. The source code is OK.
b)No. The source code cannot be compiled.
b)No. The source code cannot be compiled.
Question 10 :
Question 11 :
What about the following source code. Can it be compiled?
The accounting departement needs to know, how many baskets we produce. So we've changed the class Basket:
class FruitHelper {background:#FFFFFE; border:none; padding:0in; }
public class Basket<E> {
... private static int theCount = 0; public static int count() { return theCount;
a)No compile error, no exception during the runtime b)Compile error in the line 3 c)ClassCastException the line 3 d)Compile warning in the line 3, ClassCastException in the line 4 e)Compile warning in the line 3, ClassCastException in the line 5
} Question 13 : Basket() { ++theCount;
And what about this one?
} Basket bG = new Basket(); // 1 ... }
Basket extends Fruit> b = bG; // 2 if (b instanceof Basket<Apple>) { // 3 Basket<Apple> bA = (Basket<Apple>) b; // 4
What output would be produced by the following source code? public static void main(String[] args) { Basket<Apple> bA = new Basket<Apple>(); Basket bG = new Basket(); System.out.println(bA.count()); a)1 b)2 c)Compiler error
bA.setElement(new Apple()); // 5 } // 6 Orange g = bG.getElement(); // 7 a)No compiler error, no exception b)Compiler error in the line 3 c)Compiler warning in the lines 3 and 4. An exception will be thrown in the line 7.
Question 14: Question 12 : What abut the following source code? Basket bG = new Basket(); // 1 Basket b = bG; // 2 Basket<Apple> bA = (Basket<Apple>)b; // 3 bA.setElement(new Apple()); // 4 Orange g = bG.getElement(); // 5
The last question is about arrays and generics. Which of the following lines can be compiled? a)Basket<Apple>[] b = new Basket<Apple>[10]; b)Basket>[] b = new Basket<Apple>[10]; c)Basket>[] b = new Basket>[10]; d)public T[] test() {return null;} e)public T[] test() {return new T[10];} Answers:
Answer1 : b)The usage of generics has no implications for the runtime performance of the compiled programs The Java Virtual Machine and the copiled byte code are Generics agnostic. The comiled byte code does not differ from byte code compiled from sources which don't use the generics. So using the generics has no impact on the runtime performance of compiled Java code. Answer2 : c
c) No, a cast is not necessary. In a type safe code bO can contain only an orange. But our code is not type safe, because we use the generic class Basket<E> without specifying the concrete type for the type variable E. That is why we will be warned by the compiler. Answer7 : d, e a)No, not type safe and line 1 would need a cast b)Better, but would not work with Basket<Jonagold> c)No. We would need an cast in the line 1.
The line 2 is ok. The line 3 however will cause a runtime error. The result type of the methode getElement of Basket is Fruit. We cannot assign a Fruit to a variable of the type Apple without a cast. Answer3 : d
d)Yes. This is the correct answer e)Also corret, but a bit too verbose. f)Looks nice, but the syntax is not correct.
Both Apples and Oranges are Fruits and can be inserted into a Basket. That is why the cast is necessary in the line 3.
Answer8 : d
During the runtime the JVM checks the cast in line 3 and throws a ClassCastException since an Apple is not a Orange.
a)The call insertRipe(new Apple(), new Basket()); would not be allowed. But it is possible to insert an Apple into a Basket.
Answer4 :a,b,c, and f Answer5 : a,b
a) b)
a) The compiler does not know the type of the element stored in b5. That is why it cannot guarantee an apple can be inserted into the basket b5. So the statement s5.setElement(new Apple()) ist not allowed. The methode b5.setElement(..) cannot be used at all. b) The compiler does not know the type of the element stored in b. That is why it cannot guarantee apples can be inserted into the basket b. But since we did not specify the type of the element of b at all, the compiler will accept the source code and compile it as if it was a pre 1.5 source code. Since the compiler cannot assure the type safety of the compiled code, it will issue a warning.
Answer6 : d
b)Compile error in the line 2. c)A bit better, but the call insertRipe(new Jonagold(), new Basket<Jonagold>()); would not be allowed. But it is possible to insert a Jonagold into a Basket<Jonagold>. d)Yes, this is the correct answer. E0No, the compiler would not like it. Answer9 : b No, unfortunately this source code cannot be compiled. Method names can only be overloaded if the count or the types of the methods differ. The compiler erases the type information form the generics and so both isRipeInBasket methods have the same signature. This is not allowed. (This is a major difference to the templates in C++)
Answer10: a This source code is OK. The compiler converts the signatures of the insertRipe methods to the following ones: public static void insertRipe(Apple a, Basket b) public static void insertRipe(Orange g, Basket b) Those signatures are different and so the method name can be overloaded. Answer1 1: b There is only one compiled class Basket and so is there only one static variable Basket.theCount. Answer1 2: e During the runtime the JVM has no information about the types used in the type variable E. That is why it cannot check to see, whether the cast (Basket<Apple>)b is valid. The cast is reduced to (Basket)b and that is why there will be no ClassCastException the line 3. (But the compiler will warn us about the type unsafety) Answer1 3: b Well, according to the Tutorial the choice b) shold be correct. JDK 1.5.0 Beta 1 behaves like described in c). Beta 2 corrects the behavior. Answer1 4: c & d Arrays of generic types are only allowed, if the values of the type variables is the unbounded wildcard.