2015-12-14 3 views
3

Ниже приведены два метода в классеErasure методы такой же, как другой метод в типе

класса разработчики и студенты различны и не разделяют какие-либо из родителей.

Оба метода имеют одинаковый код и метод, называемые обоими объектами, имеют одинаковое имя ex. getStartDate.

class hierarchyValidator { 
    private LocalDate[][] getArrayOfTimespan(List<Developer> developers) 
    { 
     //here i have to call some method on developer from list 
     LocalDate startDate = developer.getStartDate(); 
     .... 
    } 

    private LocalDate[][] getArrayOfTimespan(List<Student> students) 
    { 
     //here i have to call some method on student from list 
     LocalDate startDate = student.getStartDate(); 
     ..... 
    } 
} 

Он показывает ошибку Erasure метода такой же, как другой метод в типе

Я понимаю причину ошибки от другого поста на одном сайте.

Как переупорядочить его так, чтобы ошибка не была там, и код будет чистым?

+0

Вы используете Java 8? – WalterM

+0

Я использую версию java 6 –

+0

@WalterM oh, тогда время Joda. Scratch мой предыдущий комментарий :) – Mena

ответ

5

Ваша проблема связана с type erasure: информация о параметризованном типе в вашем List s удаляется во время выполнения, поэтому методы имеют практически идентичную подпись и ваш код не может скомпилироваться.

Для того, чтобы решить проблему, вот решение, которое обобщает общие черты Developer и Student, таким образом, только требует одинgetArrayOfTimespan метод для обоих заданных параметризованных типов:

// common interface to Student and Developer classes 
interface Datable { 
    LocalDate getStartDate(); 
} 
// dev class implementing "datable" 
class Developer implements Datable { 
    @Override 
    public LocalDate getStartDate() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 
// student class implementing "datable" 
class Student implements Datable { 
    @Override 
    public LocalDate getStartDate() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
} 
// parameter interpreted as list of super type to both dev and student 
private LocalDate[][] getArrayOfTimespan(List<Datable> args) 
{ 
    for (Datable d: args) { 
     // TODO something 
     LocalDate foo = d.getStartDate(); 
    } 
    // TODO return something 
    return null; 
} 
1

Это врожденная проблема с Java-дженериками. Поскольку общие типы стираются во время выполнения, jvm не может решить, какую версию метода getArrayOfTimespan() вызывать, так как оба будут иметь одну и ту же подпись: то есть getArrayOfTimespan(List<Object> arg1). Отсюда и ваша ошибка. Однако, если мы выходим за пределы общих возможностей Java, это ограничено, компилятор Java фактически говорит вам, что у вас есть более глубокая проблема.

Кажется, что обе ваши Student и Developer классы разделяют поведение в какой-то степени, так как оба имеют одинаково названный метод, который делает то же самое: getStartDate(). Это предполагает, что вы можете объявить интерфейс, который определяет это обычное поведение, например. «Начать», а затем вам нужно будет только определить метод getArrayOfTimespan() для интерфейса.

interface Startable { 
    LocalDate getStartDate(); 
} 

class Student implements Startable { /* ... */ } 

class Student implements Startable { /* ... */ } 

class hierarchyValidator { 
    private LocalDate[][] getArrayOfTimespan(List<Startable> startables) 
    { 
     // ... 
     LocalDate startDate = startable.getStartDate(); 
     // ... 
    } 
} 

Продолжая на этом пути вы, вероятно, заметите, что вы делаете некоторые копирования-вставки между вашими Developer и Student классов, как я предполагаю, что они не только разделяют общее поведение, но и общая структура (не менее private LocalDate startDate;). Это всегда является показателем того, что вы должны извлекать свою общую структуру и поведение в абстрактный класс. Например:

abstract class Person { 
    private LocalDate startDate; 

    public LocalDate getStartDate() { 
     return this.startDate; 
    } 
    // ... etc ... 
} 

class Student extends Person{} 

class Developer extends Person{} 

class hierarchyValidator { 
    private LocalDate[][] getArrayOfTimespan(List<Person> people) 
    { 
     // ... 
     LocalDate startDate = person.getStartDate(); 
     // ... 
    } 
} 

Это не только сэкономит вам много копирования вставки, но это будет также сделать код более ясным для других, и поможет вам избежать ошибок, когда вы меняете вещи в одном месте и забыть о копии.

Итак, вкратце: если вы понимаете, что вы заняты копированием, или если у вас проблемы с генериками, это почти всегда означает, что вам нужно наследование. Если ваши классы имеют общее поведение (т. Е. Имеют одинаковые методы) -> используйте интерфейс. Если ваши классы имеют общую структуру (т. Е. Имеют одинаковые поля) -> используйте абстрактный класс.

Надеюсь, что это поможет, и удачи!

0

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

class HierarchyValidator { 
    private LocalDate[][] getArrayOfDeveloperTimespan(List<Developer> developers) { 
     //here i have to call some method on developer from list 
     LocalDate startDate = developer.getStartDate(); 
     .... 
    } 
    private LocalDate[][] getArrayOfStudentTimespan(List<Student> students) { 
     //here i have to call some method on student from list 
     LocalDate startDate = student.getStartDate(); 
     ..... 
    } 
} 

Теперь эти два метода не перегружать друг друга, позволяя продолжить отдельные реализации.