Przez niewirtualizowanie pól chciałem określić takie zachowanie:
class A {
final int i = 5;
}
class B extends A {
final int i = 6;
}
public class Main {
public static void main(String[] args) {
B b = new B();
A a = b;
System.out.println(a.i);
System.out.println(b.i);
}
}
Chociaż w sumie teraz widzę, że jeden z moich komentarzy o niemożliwości zamiany pól na static jest nieprawdą - skoro pola, a co za tym idzie stałe, są niewirtualizowane, to spokojnie można by te stałe przerobić na static. Problem w tym, że pola niestatyczne typu final można zmienić przez refleksję, oraz te pola instancji typu final mogą mieć różne wartości w różnych instancjach.
To o czym ty napisałeś to osobny problem.
Wczesne wiazanie znaczy 'wiazanie na etapie kompilacji'.
Gdzie jest ten etap kompilacji w Javie? Kod jest przekompilowywany w kółko, np weźmy przykładowy kod:
List lista = pobierzListę();
for (Object coś : lista) {
System.out.println(coś);
}
JVM może stworzyć coś takiego:
List lista = pobierzListę();
if (lista instanceof ArrayList) {
ArrayList listaArrayList = (ArrayList) lista;
for (Object coś : listaArrayList) {
System.out.println(coś);
}
} else {
przekompilujKod();
}
Taki mechanizm siedzie w JVM. Gdzie tutaj jest etap kompilacji, co oznacza w tym przypadku wczesne i późne wiązanie? Wg mnie te terminy są mało dokładne jeśli chodzi o JVM.
Jego kod rowniez nie rzuca wyjatku...
Zachowanie kodu jest zgodne z moim komentarzem.
Podsumowując, w Javie, żadne z tych rzeczy nie są polimorficzne:
- pola w klasach,
- statyczne pola i metody/ klasy,
- wywoływanie metod (na co zwrócił uwagę jambalaya),
- pewnie coś tam jeszcze,
C#, mimo że sporo młodszy, to skopiował te błędy. Ale mam nadzieję, że niedługo pojawi się język (i platforma), który niweluje te błędy.