tags:

views:

160

answers:

4
public class StateQueryFilter extends FieldQueryFilter {
   // private static final Log LOG = LogFactory.getLog(RecommendedParser.class.getName());

    public StateQueryFilter() {
        super("state", 5f);
     super("city", 5f);
     super("notdirectory", 5f);
        //LOG.info("Added a state query");
    }

}

And it reports:

Constructor call must be the first statement in a constructor

Is there a way to make it work?

+7  A: 

You can only call super once in a constructor, and it must be the first line.

It does not even make sense to call it more than once as you are doing. Calling super does not create a new object; it just lets the superclass initialize its fields. Are you really trying to initialize the same fields more than once? You probably are trying to create three separate objects, but that is not the way to do it.

See also Using the keyword super in the Java tutorials.

Michael Myers
It's a code in my nutch plugin for nutch0.9,used to work.
Shore
There is no way it ever worked, unless they changed the rules drastically several versions ago.
Michael Myers
*That* code has never worked - it's never been legal to call super(...) more than once.
Jon Skeet
Lol, I love how people up-vote Skeet even if the same answer was given already, yet don't up-vote that answer. You've become a self fulfilling prophecy Jon :)
Gandalf
+2  A: 

Nope. You are trying to construct the object 3 times, the logic is flawed.

Gandalf
but it used to work,say,with nutch0.9.
Shore
+2  A: 

From section 8.8.7 of the Java Language Specification:

The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass (§8.8.7.1).

Note "first" statement - you can't have more than one.

Jon Skeet
Aww! I was going to go find it in the JLS, but now I'd look like an answer thief. :(
Michael Myers
+2  A: 

I find constructors which call setter ugly.

Another option is to have a constructor which takes the arguments.

public StateQueryFilter() {
    super(/*state*/ 5, /* city */ 5, /*notdirectory*/ 5);
    //LOG.info("Added a state query");
}

However it looks like you should be doing something like

public class StateQueryFilter extends FieldQueryFilter {
    private final String city;
    private final String state;
    private final boolean noDirectory;

    public StateQueryFilter(String city, String state, boolean noDirectory) {
        this.state = state;
        this.city = city;
        this.notDirectory = notDirectory;
    }
}
// later
FieldQueryFilter filter = new StateQueryFiler("Los Angeles", "California", true);

BTW: Don't use float values, they are almost never the best option.

Peter Lawrey
Second the recommendation to avoid floats.Also, calling setters from a constructor can actually lead to problems if the setter gets overridden in a child class do to how the vtable isn't fully constructed. Hopefully, your compiler will inline them for you, but inlining it as you do here is probably the right decision.
James
Some of this is dictated by the API: http://lucene.apache.org/nutch/apidocs-0.9/org/apache/nutch/searcher/FieldQueryFilter.html .
Michael Myers