Потому что информация, которую вы дали компилятору, позволяет вам делать то, что вы делаете. Недопустимо только состояние времени выполнения. Ваша переменная h
объявлена как HashMap[]
, что означает, что для h
все, что реализует HashMap
, является допустимым элементом. PrinterStateReasons
реализует HashMap
, и поэтому h[0] = new PrinterStateReasons();
является совершенно допустимым утверждением. Точно так же, поскольку LinkedHashMap
реализует HashMap
, оператор HashMap[] h = new LinkedHashMap[4];
является совершенно допустимым оператором. Только в время выполнения вы пытаетесь сохранить объект PrinterStateReasons
как элемент в массиве LinkedHashMap
, что вы не можете сделать, так как он не совместим с назначениями.
Два высказывания, которые вы дали, являются смежными, но, конечно, обобщенная реальность гораздо сложнее. Рассмотрим:
HashMap[] h = foo.getHashMapArray();
h[0] = new PrinterStateReasons();
// ... elsewhere, in some `Foo` class -- perhaps compiled
// completely separately from the code above, perhaps
// even by a completely different team and even a different
// compiler -- and only combined with the code above at runtime...
public HashMap[] getHashMapArray() {
return new LinkedHashMap[4];
}