Java generics code compilation issues when building outside of Eclipse
I have configured a Maven build for a very small GWT project I'm having. Compiling/running from Eclipse causes no problem, but when I execute Maven build, I've got compilation issues in one single place (this is GWT 'client-side' code, but I'm not sure if that's the case). Maven/compile output:
[..]SmartTable.java:[63,52] ')' expected
[..]SmartTable.java:[63,53] ')' expected
[..]SmartTable.java:[63,69] ';' expected
[..]SmartTable.java:[63,71] not a statement
[..]SmartTable.java:[63,77] ';' expected
[..]SmartTable.java:[63,79] not a statement
.. where this specific line defined as following:
final Comparator<T> comparator = ((SmartTable<T>.ComparableColumn) column).comparator;
As you have guessed, I'm iterating over all columns defined for this generics-class (which I call 'SmartTable'), and getting a comparator (of course, if column instanceof SmartTable.ComparableColumn) for further operations. Classes 'Column' and 'ComparableColumn' are nested in SmartTable, and their headers looks as following:
public abstract class Column {
// private String id;
private String caption;
private int width;
private Filter<T> filter;
...
public class ComparableColumn extends Column {
private Comparator<T> comparator;
...
When it gets compiled from Eclipse, I have no problems in packaging WAR (without 'clean' - simply package which will work since Eclipse configured to place .class files in the same target directory used by Maven) and deploying/running it correctly.
I've already tried changing maven-compiler-plugin and configuration (setting values 1.5, 1.6; and 1.4 - for sake of experiment to see if it will start complain on generics in general), but that wasn't of help. Eclipse project compiler compliance is default (1.6). It seems that I have no other compilation issues with the other generics code.
Tried to make it as short as possible, but not sure if I managed to do it well :)
EDIT: More of code by demand
public class SmartTable<T> extends FlexTable {
private List<Column> columns = new ArrayList<Column>();
...
private Comparator<T> currentComparator;
...
public void init(Comparator<T> defaultComparator) {
this.currentComparator = defaultComparator;
...
int index = 0;
for (Column column : columns) {
...
if (column instanceof SmartTable.ComparableColumn) {
@SuppressWarnings("unchecked")
final Comparator<T> comparator = ((SmartTable<T>.ComparableColumn) column).comparator;
...
}
...
public abstract class Column {
// pr开发者_运维问答ivate String id;
private String caption;
private int width;
private Filter<T> filter;
private List<WidgetCreator<T>> widgetCreators;
public Column(/* String id, */String caption, int width, Filter<T> filter, List<WidgetCreator<T>> widgetCreators) {
...
public class SimpleColumn extends Column {
public SimpleColumn(/* String id, */String caption, int width, Filter<T> filter, List<WidgetCreator<T>> widgetCreators) {
super(/* id, */caption, width, filter, widgetCreators);
}
...
public class ComparableColumn extends Column {
private Comparator<T> comparator;
public ComparableColumn(/* String id, */String caption, int width, Filter<T> filter,
List<WidgetCreator<T>> widgetCreators, Comparator<T> comparator) {
super(/* id, */caption, width, filter, widgetCreators);
this.comparator = comparator;
}
...
}
EDIT2: Actual problem seems to be very concentrated :)
public class SmartTable2<T> {
public void init() {
Column c = new ComparableColumn();
final Comparator<T> comparator = ((SmartTable2<T>.ComparableColumn) c).comparator;
}
class Column {
}
class ComparableColumn extends Column {
Comparator<T> comparator;
}
}
EDIT3: Some thoughts, hopefully closer to the solution .. so this doesn't compile simply with javac, throwing exactly same compilation errors. So what I've learned just now: Eclipse uses it's own internal Java compiler - which is part of JDT Core (hope I have not misunderstood it); so might it be the case that JDT Compiler is able to compile such a syntax, while Sun's JDK javac is not??? (oops, Oracle not Sun)
Try this syntax:
Comparator<T> comparator = (Comparator<T>) ((SmartTable.ComparableColumn) column).comparator;
EDIT: The cast is useless:
Comparator<T> comparator = ((SmartTable.ComparableColumn) column).comparator;
Does this resemble your scenario ?
public class Main {
public static <T> void main(String[] args) throws Exception {
SmartTable<T>.Column column = new SmartTable<T>().new Column();
Comparator<T> comparator = ((SmartTable.ComparableColumn) column).comparator;
}
static class SmartTable<T> {
class Column {
}
class ComparableColumn extends Column {
Comparator<T> comparator;
}
}
}
This compiles fine with javac (with unchecked warnings, of course), while trying to compile the cast to (SmartTable.ComparableColumn) results in exactly the errors in your post.
EDIT (of all edits): Your question seems to have been asked before: Casting to an inner class with generics and the answer seems to be a compiler bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6665356
Use it the following way. I mean add the following plug in directly to the pom.xml file.
org.apache.maven.plugins maven-compiler-plugin 1.5 1.5
精彩评论