2013-06-27 3 views
0

Просто прыгать в Java генериков, и я столкнулся с немного проблема: я не могу показаться, чтобы вызвать метод параметризованного типа:Как вызвать метод параметризованного типа?

class test 
{ 
    public static void main(String args[ ]) 
    {  
     invoke_baz(new foo()); 
    } 
    public static <Type> void invoke_baz(Type object) 
    { 
     object.baz(); 
    } 
    public static class foo 
    { 
     public void baz() 
     { } 
    }  
} 

Что я здесь отсутствует?

ответ

5

Вы указали свой общий параметр типа Type, но это может быть что угодно, а не только foo, например String.

Ограничить type с верхней границей, так что вы знаете, что это какая-то foo:

public static <Type extends foo> void invoke_baz(Type object) 

Или просто попросить foo в ваших рассуждениях, удаляя потребность в дженериков:

public static void invoke_baz(Foo object) 
+0

+1 По предложению использовать полиморфизм, а не generics –

+0

Итак, Java Generics - это не столько универсальное средство программирования, сколько «синтаксический сахар», чтобы избавить пользователя от необходимости делать явные приведения в определенных ситуациях - получилось! :) Я предполагаю, что мне просто придется полагаться на старые, старомодные методы «копировать, вставлять, искать и заменять», которые я узнал, когда я использовал C ... – SeaBass

+0

Дженерики в Java - это когда класс (или метод) имеет отношение к определенному, но неизвестному типу. Здесь известен тип: 'foo', поэтому генерики не нужны. – rgettman

0

Java не утка набрана, средство проверки типов не может понять, что общий метод вызывает метод, доступный для объекта, который вы затем передаете методу. Он должен правильно проверять этот общий код независимо от вашего конкретного случая.

Вы должны в полной мере ощутить это, явно объявив переменную типа ограничивается определенной иерархии классов так, чтобы тип проверки можно сделать предположения о нем:

interface Bazzable { 
    public void baz(); 
} 

public <Type extends Bazzable> void invoke(Type object) { 
    object.baz(); 
} 

public class Foo implements Bazzable { 
    public void baz() { 
    System.out.println("baz"); 
    } 
} 

Таким образом, вы указываете, что тип переменной по крайней мере, Bazzable, поэтому вам будет запрещено передавать только определенные типы методу, но с другой стороны вы сможете вызвать любой метод, указанный в Bazzable.

0

Вы не можете, потому что это тип универсального типа не известен во время компиляции. Компилятор не знал, что это за тип - и не вы. Один из подходов заключается в выполнении выполнения. Прежде всего, необходимо решить, какой тип вы ожидаете, и вы можете сделать что-то вроде этого:

public static <Type> void invoke_baz(Type object) 
{ 
    SomeClass someClass = (SomeClass) object; 
    someClass.baz(); 
} 

Это будет конечно производить ввергнуть ошибку, если указанный объект/тип не относится к типу SomeClass.

Лучше было бы объявить интерфейс, который обеспечит контракты вашего метода, например:

public interface HaveBaz { 
    baz(); 
} 

И запрос подтип этого интерфейса на вашем родовом объявлении метода

public static < Type extends HaveBaz > void invoke_baz(Type object) 
{ 
    object.baz(); 
}