2012-01-21 6 views
6

Рассмотрим:имя Дженерики столкновение

public interface Foo<T> { 
    public static class X{} 
    public void foobar(T t); 
} 

public class Bar<X> { 
    Foo<X> foo = new Foo<X>() { 
     public void foobar(X t) {} 
    }; 
} 

Я не нашел способ выразить, что я имею в виду X от Bar<X> и не Foo.X в foobar(X t) реализации. Нет другого пути, кроме переименования общего параметра X в Bar или статического внутреннего класса?

+2

Это выглядит не так ... может вам встраивать публичный класс (даже статический) внутри интерфейса? –

+0

Да, если вы переименовываете либо статический внутренний класс, либо общий параметр Bar, он компилируется. – Landei

+2

@ Даниэль ... Да, вы можете. Это выглядит забавно, но вполне допустимо. –

ответ

9

Я не думаю, что есть способ однозначно изменить параметр типа, и я думаю, что это было разумное дизайнерское решение.

  1. Соглашения ясно показывают, что параметры типа должны быть по одному символу, если это возможно, и обратная сторона этого заключается в том, что другие классы не должны иметь односимвольные имена.
  2. Если бы у вас была возможность устранить несоответствия, , то у вас будет возможность переименовать тип параметра X в Bar<X>. Другими словами, если бы у вас была возможность сказать foobar(TypeParameter.X t), у вас была бы возможность просто использовать что-то отличное от X для параметра типа на Bar. Переименование X- путь, вы избегаете конфликтов имен.

Не забывайте, что имена параметров типа не распространяются на другие классы более чем тривиальным образом. Вы никогда не должны использовать определенное имя параметра типа. Поэтому имеет смысл, что разработчики языка не подумали бы, что это стоит добавить сложность для языка.

+0

Я склонен согласиться с вашим вторым моментом, но не с первым: отсутствие синтаксиса Java для таких простых вещей, как Closures или Tuples, заставляет вас использовать обертки, а если вы работаете над кодом, сильно полагающимся на эти обертки, вы быстро начинаете использовать имена типа 'F' или' P' вместо 'Function' или' Product' (см., например, http://www.functionaljava.org). – Landei

0

компилятор обыкновение даже беспокоить, чтобы определить, если вы имели в виду foo.x, он будет считать TypeParameter X, независимо, если вы набрали что-то вроде:

public class Bar<X> { 
    Foo<X> foo = new Foo<X>() { 
     public void foobar(Foo.X t) {} 
    }; 
} 
+0

Нет, это неправда. Внутри анонимного класса мы находимся в классе класса 'Foo', поэтому' Foo.X' затеняет параметр типа 'X' внешнего класса. – Landei