Distinguish checked exceptions, super access, hash collisions, numeric precision, and the two stages of Java method selection.
Answer: If a parent method declares FileNotFoundException, an override cannot declare unrelated SQLException or broader IOException or Exception. It may declare FileNotFoundException, a checked subtype of it, or no checked exception.
The rule concerns checked exceptions that can escape the method. The override can catch other checked exceptions internally. RuntimeException and Error subclasses are unchecked, so their declarations are not limited by the parent's throws clause.
Answer: An overriding instance method supplies behavior for an eligible method in a supertype. It can override a concrete class method or implement an abstract class or interface method. An interface can also override a method inherited from a superinterface.
Private methods are not inherited and cannot be overridden; static methods are hidden. A final method cannot be overridden. An annotation such as @Override verifies the relationship but does not create it by itself.
Answer: A blanket âneverâ is incorrect. In a suitable instance context, super.utility() can legally select an accessible static method in a superclass. That call is not overriding or virtual dispatch; class-name qualification is clearer for a static operation.
Inside a static context, super cannot be used to supply a current superclass instance, because there is no current instance. By contrast, super.instanceMethod() in an appropriate instance context explicitly invokes superclass behavior rather than dispatching back to the current class's override. Constructor early-construction restrictions also apply.
Answer: Overloading provides more than one applicable declaration with the same method name and distinct parameter signatures. Parameter number, types, or order can distinguish overloads; parameter names and return type alone cannot.
For example, parse(String) and parse(String, int) can be overloads. Overloads can involve inherited methods as well as methods declared together. Avoid collections of unrelated overloads that make null, boxing, or varargs calls surprising.
Answer: Yes. Such a collision is allowed. The essential direction of the contract is that objects equal according to equals must have equal hash codes. Equal hash codes do not prove equality.
Hash-based collections use equality checks as well as hashes to distinguish keys. When overriding equals, also supply a compatible hashCode implementation. Do not mutate equality-relevant state while an object is being used as a hash-map key unless the collection's use is carefully managed.
Answer: Float uses the IEEE 754 binary32 value set and double uses binary64: 32 and 64 bits, respectively. Double provides a wider exponent range and 53 bits of significand precision, compared with float's 24 bits.
âDouble the bitsâ is a useful memory aid for the format sizes, but it does not mean exactly double the decimal precision. Neither type represents every decimal fraction exactly. Both support infinities, NaN, and signed zero.
Answer: The compiler selects the overload. It determines which declarations are applicable and which is most specific under the method-invocation rules. It does not revisit overload selection based on each argument object's runtime class.
If the selected method is an overridable instance method, a later runtime dispatch can still choose an overriding implementation. These are separate decisions, so compile-time overload selection does not imply that every part of the call is statically bound.
Answer: The compiler considers the receiver's compile-time type, accessible declarations, argument expressions and types, generic inference, and applicable conversions. Fixed-arity applicability is considered before variable-arity invocation; boxing can also affect the selection phase.
It is incomplete to say only âthe reference type decides,â because primitive arguments, lambdas, generics, and conversions can matter. If no uniquely most-specific applicable declaration can be selected, the call is a compile-time error rather than a runtime guess.
Answer: Give a receiver two overloads and override one of them in a subclass. The compile-time argument type selects the signature; the runtime receiver then selects the override for that signature.
public class TwoStageCall {
static class Base {
String show(Object value) { return "Base Object"; }
String show(String value) { return "Base String"; }
}
static class Child extends Base {
@Override String show(Object value) { return "Child Object"; }
}
public static void main(String[] args) {
Base receiver = new Child();
Object value = "Java";
System.out.println(receiver.show(value));
System.out.println(receiver.show("Java"));
}
}
The output is Child Object followed by Base String. The String object stored in value does not cause the compiler to select the String overload for the first call.
Answer: Runtime subtype polymorphism does not choose among overload signatures. It chooses an overriding implementation after the compile-time signature has been selected. The expression's compile-time type can therefore affect behavior even when two expressions refer to the same object.
When explaining a call, identify the selected declaration first, then ask whether that declaration participates in virtual dispatch. This avoids mixing up an argument's runtime class with the receiver's runtime class.
References: JLS: method invocation, JLS: inheritance, JLS: floating-point types, and Object equality and hashing.