Этот вызов выбирается в время компиляции . Так что это не столько оптимизация, сколько сам компилятор, выбирающий, какой метод вызывать. Приведение предназначено для помощи компилятору и не повлияет на производительность во время выполнения.
Это отличается от переопределения, при котором вызываемый объект диктует метод во время выполнения, например,
shape.getArea(); // determined by whether shape is a square, circle etc.
Если вы напишите выше с / без приведения и сгенерируете байт-код (javap -verbose -c C
), вы увидите эту разницу в сгенерированном коде:
< 2: invokestatic #7; //Method m:(Ljava/lang/Object;)V
---
> 2: invokestatic #7; //Method m:(Ljava/lang/String;)V
т.е. компилятор просто выбрал другой метод (const #7
будет меняться в каждом случае, чтобы отразить этот другой метод).