Re[5]: Генерики, наследование
От: aka50 Россия  
Дата: 16.05.07 11:23
Оценка: 13 (2)
Здравствуйте, Petrovich_Alex, Вы писали:

P_A>Здравствуйте, bolshik, Вы писали:


A>>дадим один фейковый параметр, из которого компилятор может попытаться вывести тип:


P_A>что то, здесь я не нашел про фейковый параметр.


Это было про List<Object> т.е. про несовместимость типов. Про необходимость фейк-параметра здесь

If the type parameter does not appear in the types of the method arguments, then the compiler cannot infer the type arguments by examining the types of the actual method arguments. If the type parameter appears in the method's return type, then the compiler takes a look at the context in which the return value is used. If the method call appears as the righthand side operand of an assignment, then the compiler tries to infer the method's type arguments from the static type of the lefthand side operand of the assignment

далее по тексту:
An invocation context other than an assignment is not considered for type inference. The result of the method call might be passed as an argument to another method, for instance. The compiler does not try to perform any special type inference in that case. Instead the compiler handles the method call as though it would appear in no context. No context means that the compiler performs the type inference algorithm as though the method result was assigned to a variable of type Object .

Как видишь, у нас тут никакого assigment-а нету, следовательно нету и inference, а значиццо будет MyFilter<Object>. Но если мы поможем компилятору и дадим ему параметр (чтобы сработал inference) то тип будет выведен. Т.е. данной задаче нужно придумать такую конструкция параметра фабрики, чтобы можно было вывести тип. Либо указывать его явно (что ИМХО более правлильное решение).
Re: Генерики, наследование
От: aka50 Россия  
Дата: 15.05.07 19:57
Оценка: 1 (1)
Здравствуйте, Petrovich_Alex, Вы писали:

P_A>собстенно, почему есть ошибка в строке

P_A>
P_A>clean(list, newFilter());  
P_A>


Могу ошибаться, но видиться проблема в том, что Filter<T> выводится в Filter<Object> т.к. у newFilter нет параметров, далее Filter<Object> поднимается до extends A, т.е. до Filter<A>. Т.к. из-за отсутсвия в яве ковариантности по параметру дженерика Filter<A> и Filter<B> это разные несовместимые типы, и Iterable<A> и Iterable<B> тоже несовместимы типы, то следовательно удовлитворить сигнатуре (Iterable<B>, Filter<A>) компилятор не может.

Проверим догадку и дадим один фейковый параметр, из которого компилятор может попытаться вывести тип:

public class Sample2 {
    public static void main(String[] args) {

        List<B> list = new ArrayList<B>();
        clean(list, newFilter(B.class)); 
    }

    private static <T extends A> Filter<T> newFilter(Class<T> clz) {
          return new MyFilter<T>();
      }

    private static <T extends A> void clean(Iterable<T> iterable, Filter<T> filter) {
        for (Iterator<T> iterator = iterable.iterator(); iterator.hasNext();) {
            T t = iterator.next();
            if (filter.accept(t))
                System.out.println(t);
            else
                System.out.println("Rej: " + t);
        }
    }
}


Похоже что вывел
$ javac Sample2.java
$ java Sample2      
Rej: B@3e25a5
Rej: B@19821f
Re[3]: Генерики, наследование
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 16.05.07 08:32
Оценка: 1 (1)
Здравствуйте, Petrovich_Alex, Вы писали:

P_A>Здравствуйте, aka50, Вы писали:


>>Filter<A> и Filter<B> это разные несовместимые типы


P_A>а Filter<? extends A> и Filter<B> разные типы?


разные


P_A>где об этом можно почитать?


здесь
http://denis-zhdanov.blogspot.com
Генерики, наследование
От: Petrovich_Alex  
Дата: 15.05.07 18:17
Оценка:
собстенно, почему есть ошибка в строке
clean(list, newFilter());

и что можно сделать что бы не писать самому ТИП как в
clean(list, new MyFilter<B>());


код:
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

public class Sample {
    public static void main(String[] args) {

        List<B> list = new ArrayList<B>();

        clean(list, new MyFilter<B>());
                
        //error{
        // <T>clean(java.lang.Iterable<T>,Filter<T>) in Main cannot be applied to 
        //         (java.util.List<B>,    Filter<A>)
        clean(list, newFilter()); 
        //}
    }

    private static <T extends A> Filter<T> newFilter() {
          return new MyFilter<T>();
      }


    private static <T extends A> void clean(Iterable<T> iterable, Filter<T> filter) {
        for (Iterator<T> iterator = iterable.iterator(); iterator.hasNext();) {
            T t = iterator.next();
            if (filter.accept(t))
                System.out.println(t);
        }
    }
}

interface A {
    boolean isA();
}

class B implements A {
    public boolean isA() {
        return false;
    }
}

interface Filter<T> {
    boolean accept(T t);
}

class MyFilter<T extends A> implements Filter<T> {
    public boolean accept(T t) {
        return t.isA();
    }
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Генерики, наследование
От: Petrovich_Alex  
Дата: 16.05.07 08:18
Оценка:
Здравствуйте, aka50, Вы писали:

>Filter<A> и Filter<B> это разные несовместимые типы


а Filter<? extends A> и Filter<B> разные типы?


public static void main(String[] args) {

    //почему это работает
    List<? extends A> list = new ArrayList<B>();

    //а это нет: error{
    //clean(java.lang.Iterable<T>,Filter<T>) in Main cannot be applied to 
    //(java.util.List<capture#995 of ? extends A>,MyFilter<B>)
    clean(list, new MyFilter<B>());
    }
}




A>дадим один фейковый параметр, из которого компилятор может попытаться вывести тип:


где об этом можно почитать?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Генерики, наследование
От: Petrovich_Alex  
Дата: 16.05.07 09:47
Оценка:
Здравствуйте, bolshik, Вы писали:

A>дадим один фейковый параметр, из которого компилятор может попытаться вывести тип:


P>где об этом можно почитать?


B>здесь



что то, здесь я не нашел про фейковый параметр.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.