#java
#java
Вопрос:
У меня есть неизвестное количество списков (два в моем примере, но оно может варьироваться):
SimpleDateFormat sdf = new SimpleDateFormat("yyyy, MM, dd");
List<Employee> employees = new ArrayList<Employee>();
employees.add(new Employee(100, "Abe Adams", sdf
.parse("2009, 12, 1"), 10000.00));
employees.add(new Employee(101, "Betty Barnes", sdf
.parse("2010, 11, 1"), 11000.00));
employees.add(new Employee(102, "Caleb Crown", sdf
.parse("2011, 10, 1"), 12000.00));
employees.add(new Employee(103, "Dirk Daniels", sdf
.parse("2012, 09, 1"), 13000.00));
Date date = new Date();
List<ObjectTest> objects = new ArrayList<ObjectTest>();
objects.add(new ObjectTest("name",date,10.0));
objects.add(new ObjectTest("name2",date,20.0));
и я хотел бы использовать их в качестве аргумента в memthod
oReport.writeReportToExcel(employees,objects);
с
public <T> void writeReportToExcel(List <T> ... varArrayData ) {
...
}
Я должен использовать параметры аргументов var, но компилятор отклоняет код
Что нужно изменить?
Сообщение компилятора
method writeReportToExcel in class Bean2Excel cannot be applied to given types;
required: List<T>[]
found: List<Employee>, List<ObjectTest>
reason: inferred type does not conform to equality constraint(s)
inferred: ObjectTest
equality constraint(s): ObjectTest, Employee
where T is a type-variable:
T extends Object declared in method <T> wirteReportToExcel(List<T> ...)
РЕДАКТИРОВАТЬ ДЛЯ РЕШЕНИЯ (это может быть грязный способ)
Bean2Excel oReport = new Bean2Excel();
List recapList = new ArrayList();
recapList.add(employees);
recapList.add(objects);
oReport.writeReportToExcel(recapList);
И, как и было предложено, я удалил дженерики
public void writeReportToExcel(List datas) {
try {
Bean2Excel oReport = new Bean2Excel();
for (int i = 0;i<datas.size();i ){
List data = (List)datas.get(i);
...
}
}
Комментарии:
1. Можете ли вы показать нам сообщение компилятора?
2. Будут ли эти
List
s также другого типа? Если это так, вам нужно будет указать общий супертип вместоT
.
Ответ №1:
аргументы имеют разные типы, T. Вы могли бы удалить общее определение или заставить их реализовать общий интерфейс.
Обязательно ли использовать аргументы var?
Комментарии:
1. они могут быть любого типа, и да, необходимо, чтобы я использовал аргументы var, если это невозможно сделать
Ответ №2:
<T> должен быть указанным типом в методе. Например, Employee или ObjectTest здесь. Но как только вы определили 2 разных типа в методе и попытаетесь применить к списку<T>[] с именем varArrayData , компиляция откажется выполнять, поскольку она не может убедиться, что T означает Employee.class или ObjectTest.class .
Если вы действительно хотите использовать аргументы var, удалите метку <T> в подписи метода, возможно, сработает:
public void writeReportToExcel(List ... varArrayData ) {
...
}
Или вы можете поместить тип define в класс leave:
public class Bean2Excel<T>{
public void writeReportToExcel(List<T> ... varArrayData ) {
...
}
}
Надеюсь, это поможет.
Комментарии:
1. как вы предположили, я удалил метку generics, это, без сомнения, грязный способ, но он работает
2. и да, это помогло!
Ответ №3:
Как уже было сказано, я бы создал общий интерфейс, скажем WritableToExcel
, или что-то в этом роде, а затем использовал подстановочные знаки:
public void writeReportToExcel(List<? extends WritableToExcel>... varArrayData) { }
Теперь вы можете читать из списков внутри вашего метода и вызывать методы WritableToExcel
для записи вашей таблицы.
Ответ №4:
Создайте общий базовый класс для типов, которые могут входить в списки.
Если Employee
и ObjectTest
наследуется от одного и того же базового класса, он должен работать.
Комментарии:
1. Нет. Если
X
является суперклассом ofEmployee
, тоList<X>
не будет супертипом ofList<Employee>
.