简体   繁体   中英

Calling an overloaded method from an anonymous, generic class in Java

I'm trying to create an extended version of a DefaultListModel (of type String ) that accepts an object of a class I've created, called a LogItem and 'automatically' use that information to infer what data should be used to populate the relevant element.

In my code it looks like this:

public static DefaultListModel<String> log = new DefaultListModel<String>(){

    public void addElement(LogItem logItem){

        super.addElement("[" + logItem.getTimestamp() + "] " + logItem.getEvent());

    }

};

and later in the class:

log.addElement(new LogItem(event));

Yet the latter of those two sections of code gives a compile-time error:

Error:(196, 32) java: incompatible types: com.example.LogItem cannot be converted to java.lang.String

So it appears as if I, for some reason, cannot access the overloaded method I made in the anonymous class ( addElement(LogItem logitem){...} ).

I guess I must be missing something, why can't I use the overloaded class?

You have a few options:

You could use a method to get the string representation of your logItem and pass it to your DefaultListModel:

private String getLogItemAsString(LogItem logItem) {
    return "[" + logItem.getTimestamp() + "] " + logItem.getEvent();
}

then

log.addElement(getLogItemAsString(new LogItem(event)));



Maybe a nicer way to do this would be through a Utility Class:

public final class DefaultListModelUtils {

    private DefaultListModelUtils() {}

    public static final void addElement(DefaultListModel<String> defaultListModel, LogItem logItem) {
        defaultListModel.addElement(getLogItemAsString(logItem));
    }

    private static String getLogItemAsString(LogItem logItem) {
        return "[" + logItem.getTimestamp() + "] " + logItem.getEvent();
    }
}

and use it like this:

DefaultListModelUtils.addElement(log, new LogItem(event));



Or you can extend DefaultListModel<String> like this:

public class MyDefaultListModel extends DefaultListModel<String> {
    public void addElement(LogItem logItem){
        super.addElement("[" + logItem.getTimestamp() + "] " + logItem.getEvent());
    }
}

then use

MyDefaultListModel log = new MyDefaultListModel();
log.addElement(new LogItem(event));

You could also override the toString() method of you LogItem class, or implement another method for conversion if toString() is allready used:

public String toString() {
    return "[" + getTimestamp() + "] " + getEvent();
}

And then just use the regular addElement(String) :

log.addElement( (new LogItem(event)).toString() );

The declared type of the variable determines what the compiler allows, not the runtime type. The declared type of your variable log is DefaultListModel<String> , which does not have a void addElement(LogItem) method. The compiler cannot allow a call to a method not known to the declared type. It can only find void addElement(String) . And you can't call that with a LogItem argument.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM