Human JShell
%, /, * bind stronger than +, -.
% does not bind stronger than /.
(double) and any typecasting is unary and has the highest precedence!
we can modify and access static variables through this.x
Array Access Bullshit
We can create an int[][] b = new int[3][0] array that contains three empty arrays. We can then create another int[] c = new int[3] and just do b[0] = c even though the types don’t match as b only stores pointers to arrays and that’s not checked!
The lengths of arrays are not type-checked nor runtime checked.
Executing
ArrayList<...>’s method
.add()adds at the end..remove(k)removes the element at index k if given anint. If given anObjectso for exampleIntegerit will remove the object. See HS23 foral.remove(Integer.valueOf(k));
Class / Method Quiz
- Methods use the attributes from the class they’re executed in! Not from the static, not from the dynamic class, from the one the method is actually running in.
public class Thing {
private int value;
public Thing(int value) { this.value = value; }
public void increment() {
value = value + 1; // Here the attribute is used!
}
}
Thing a = new Thing(5);
Thing b = new Thing(10);
a.increment();
a.show(); // Prints: 6
b.increment();
b.show(); // Prints: 11-
When giving a reference to an object like
Integerto a methodtest(a), the method receives a copy of the reference. When it overwrites it in the method body, likea = Integer.valueOf(3), it will alias the variable. Overwriting the local reference, not the one in the program callingtestitself. Otherwise we would have to do something likea.value = 3.2 -
Dynamic Dispatch Note that the dynamic dispatch still applies inside methods of other classes (even with
this). So if we callB.a()andB extends Adidn’t override that, when insideA.a()we callb()ifBoverrode that, well go intoB.b()notA.b().
Private Overriding
Private methods cannot be overriden, they can only be redefined in subclasses. But they will be statically bound to their own class if used in any methods of the superclass, as can be seen here.
class A {
private void private_test() {
System.out.println("from private of A");
}
public void public_test() {
System.out.println("A public");
}
public void test() {
private_test(); // Statically bound to A.private_test at compile time
public_test();
}
}
class B extends A {
public void private_test() {
System.out.println("never reached");
}
@Override
public void public_test() {
System.out.println("from public of B");
}
public void testB() {
test();
}
}
B a = new B();
a.testB();
// The output is:
// "from private of A"
// "from public of B"Class Hierarchy Quiz
Use the .super() calls as hints and look out for constructors with values that call another constructor explicitly.
Don’t forget that for a cast to be valid, it needs to be a sub-class! Otherwise it’s a compile error.
Thus (C)D implies that C extends D!
Overriding
A method overriding one in it’s superclass must satisfy the following conditions:
- Same Name: The method in the subclass must have the exact same name as in the superclass.
- Same Parameters: The parameter list must match exactly (type, order, and number).
- Covariant Return Type: The return type must be the same or a subtype of the overridden method’s return type.
- Not Private, Static, or Final: Private, Static and Final methods cannot be overridden.
- Visibility: The overriding method must have equal or broader visibility: Visibility hierarchy: public > protected > default (i.e. no modifier) > private (not overridable).
WP
When there is a variable that doesn’t appear in the code block in the post condition, the pre-condition needs to imply the value!
WP: { b > 5} as b > 5 for the WP => Q
a = 1
Q: { b > 5 }
If with no else
Don’t forget the case where the if statement is false!
If there’s an if without an else, the of the if condition still needs to imply the post condition!
WP: { (a > 0 && ...) || (a <= 0 && b > 5) }
if (a > 0) {
c = 2 * a;
b = c + 1;
}
Q: { b > 5 }
Here if not a > 0 then a <= 0 and then we need to imply the postcondition so b > 5!