2018.07.26 19:37
statyczne typowanie nie jest łatwe
Czasem się zdarza, że z kimś rozmawiam i mówię, że statyczne typowanie jest trudne, a ten ktoś mi nie wierzy. W takich razach przyda mi się mieć pod ręką poniższy przykład. Nie tak łatwo dojść, czy to się w ogóle skompiluje, a jeśli nie, to jaki będzie błąd i jak to naprawić. Oto ten przykład:
abstract class Lista<T> {
public abstract boolean czyPusta();
public abstract T głowa();
public abstract Lista<T> ogon();
public Lista<T> dołącz(T liczba) {
return new Niepusta<T>(liczba, this);
}
}
class Pusta<T> extends Lista<T> {
@Override
public boolean czyPusta() {
return true;
}
@Override
public T głowa() {
throw new UnsupportedOperationException();
}
@Override
public Lista<T> ogon() {
throw new UnsupportedOperationException();
}
@Override
public String toString() {
return "-";
}
}
class Niepusta<T> extends Lista<T> {
private final T głowa;
private final Lista<T> ogon;
public Niepusta(T głowa, Lista<T> ogon) {
this.głowa = głowa;
this.ogon = ogon;
}
@Override
public boolean czyPusta() {
return false;
}
@Override
public T głowa() {
return głowa;
}
@Override
public Lista<T> ogon() {
throw new IllegalArgumentException();
}
@Override
public String toString() {
return głowa + ", " + ogon;
}
}
public class Problem {
public static void f(Lista<Number> lista) {
Number pi = 3.14;
Lista<Number> lista2 = lista.dołącz(pi);
Number głowa = lista2.głowa();
System.out.println(głowa);
}
public static <T> Lista<T> stwórzListę(T... liczby) {
Lista<T> lista = new Pusta<>();
for (T liczba : liczby) {
lista = new Niepusta<>(liczba, lista);
}
return lista;
}
public static void main(String[] args) {
Lista<Integer> mojaListaIntów = stwórzListę(3, 7, 5);
f(mojaListaIntów);
}
}
komentarze:
2018.08.17 08:07 Piotrek
Uzupełnienie: chodzi mi głównie o metodę dołącz(). Czy ona się skompiluje? Jasne że nie, bo nie byłoby zagadki. A dlaczego nie? I co zrobić, żeby się skompilowała?
2018.09.10 05:55 Piotrek
A oto druga zagadka. Czy ten kod się skompiluje? A jeśli tak, to jakiego typu jest zmienna para2 (no, oprócz tego, że jak wszystko w Javie jest typu Object)?
class A {}
class B extends A {}
class C extends B {}
class D extends C implements N1, N2 {}
class W {}
class X extends W {}
class Y extends X {}
class Z extends Y implements N1, N2 {}
interface N1 {}
interface N2 {}
class Para<T> {
private final T a;
private final T b;
public Para(T a, T b) {
this.a = a;
this.b = b;
}
public T getA() {
return a;
}
public T getB() {
return b;
}
public static <U> Para<U> replace(Para<? extends U> staraPara, U noweA) {
return new Para<U>(noweA, staraPara.getB());
}
}
public class Problem2 {
public static void main(String[] args) {
Para<D> para1 = new Para<>(new D(), new D());
Z z = new Z();
Object para2 = Para.replace(para1, z);
}
}
powrót na stronę główną
RSS