Lab 03 - Exceptions, Generics,Exercises 2,3
Exercise 2 Review
Do we need a LeaveQueueEvent?
A SerciveBeginEvent will be triggered immediately after a ServiceEndEvent with a newly dequeued customer.
Exceptions
This part is one important test point in PE0 Review. Refer to the cheatsheet there will be pretty enough.
Generics
Generic Type Parameters
Type parameters are dummy types which get substituted with concrete types when creating an instance.
Scope of Type Parameters
A class's generic type parameters cannot be used in
staticmethods orstaticfields.
This is because static means the same for all instances, but T will change based on what you instantiate them to be. Thus, class's type parameter is not allowed in static method or static field.
For example,
class A<T> {
public static T foo() {...}
public static <S> S bar1() {...}
public static <S> T bar2() {...}
public static <T> T bar3() {...}
}Line 2 and Line 4 are not allowed because they use the generic type parameter T from the class A.
To use generic type parameters in
staticmethod, you must declare Generic Methods! (a.k.a declare a type parameter in thestaticmethod again)
For example, in Line 3 and Line 5, we declare a new type parameter S and a shadowed T. This is allowed!
Classic Questions
Question 1 (Type Checking)
For the the following code,
Determine the 8 code snippets in the following table will compile or not?
Solution:
Static Methods in Generic Classes:
generic type parameters.
Example:
bar1uses<S>, andbar3uses<T>. These are method-level type parameters, unrelated to the class's<T>.
Calling Static Generic Methods:
Syntax for specifying a method's type parameter:
ClassName.<Type>method().Class type parameters (e.g.,
<Integer>inA<Integer>) are irrelevant for static methods and cannot be mixed with method type parameters in the call.
A<Integer>.<Double>bar1();
❌
Invalid syntax (mixes class/method type parameters).
A<Integer>.<Double>bar3();
❌
Same as above.
A<T>.<Double>bar1();
❌
T is undefined unless in a valid generic context.
A<T>.<Double>bar3();
❌
Same as above.
A.<Double>bar1();
✅
Correct syntax (method’s type parameter explicitly set).
A.<Double>bar3();
✅
Same as above.
A.bar1();
✅
Type inference (method’s type parameter inferred).
A.bar3();
✅
Same as above.
Question 2 (Type Checking)
For the the following code,
Determine the 5 code snippets in the following table will compile or not?
Solution:
new B<Integer>().foo();
✅
Integer
Non-generic method returns class’s T.
new B<Integer>().<String>foo();
❌
—
foo() is not generic; invalid syntax.
new B<Integer>().<String>bar1();
✅
String
Generic method’s S set to String.
new B<Integer>().<String>bar2();
✅
Integer
Method’s S is String, but returns class’s T (Integer).
new B<Integer>().<String>bar3();
✅
String
Method’s T shadows class’s T; returns String.
Takeaway:
Non-generic methods (e.g.,
foo()) cannot have type arguments specified.Generic methods (e.g.,
bar1(),bar2(),bar3()) are independent of the class’s type parameters.Shadowing (e.g.,
bar3()) creates a new type variable unrelated to the class’sT.Type Mismatch in
bar4()occurs because the method’sTis distinct from the class’sT, so you cannot returnthis.x, which is of the class'sT.
Last updated