为什么我对Java构造函数中的super()的调用被标记为错误?

时间:2011-07-30 04:43:54

标签: java constructor abstract super

我有:

  • 一个抽象的Message类,
  • 一个扩展Message的抽象CustomMessage,
  • 扩展CustomMessage的具体SpecializedCustomMessage类,

如下所示,我遇到了具体类的构造函数对super()的调用问题。我遗漏了许多我认为与我遇到的错误无关的细节。在派生具体类之前,有两个抽象级别存在问题吗?

public abstract class Message {
    private int priority;
    Message() {
        priority = 1;
    }
}
public abstract class CustomMessage extends Message {
    CustomMessage() {
        super();
    }
}
public class SpecializedCustomMessage extends CustomMessage {
    SpecializedCustomMessage() {
        /*
         * The following is flagged with the error:
         * "cannot reference this before supertype constructor has been called"
         */
        super();
    }
}

编辑:根据要求,整个文件。搜索LoadCyclerMessage()。

package ibm1620;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Class Message: an object containing an event.  See
 * PriorityFIFOEventQueue for implementation of queue.
 *
 * @author Richard Jowsey <richard@jowsey.com>
 * @author Chap Harrison <clh@pobox.com>
 */
//
//
// Extensive rewrite 7-JUL-2011 by CLH to use queuing to avoid
// having the Producer block until the Consumer catches up.
//
//
public abstract class Message implements Comparable<Message> {

    private int priority;

    Message() {
        this.priority = 1;
    }

    Message(int priority) {
        this.priority = priority;
    }

    /**
     * Comparator to determine relative priority. Called by PriorityFIFOEventQueue.
     */
    @Override
    public int compareTo(Message other) {
        // TODO - compare this and other for priority
        return 0; // no priorities yet.
    }

    /**
     * process() is overridden to handle message subclasses
     */
    public abstract void process();

    static void say(String s) {
        System.out.println(s);
    }

    /* -------------------------------------------------------------------- */
    /**
     * Subclass ConsoleEventMessage:
     */
    public static class ConsoleEventMessage extends Message {

        private ConsoleObject obj = ConsoleObject.UNDEFINED_OBJ; // widget that was affected
        private ObjectState state = ObjectState.UNDEFINED_STATE; // the widget's new state

        /**
         * Constructor specifying object and new state.
         */
        public ConsoleEventMessage(ConsoleObject theObj, ObjectState theState) {
            super();
            obj = theObj;
            state = theState;
        }

        @Override
        public void process() {
            // handleConsoleEventMessage(this);
            // what do we do now??
        }

        /**
         * Message accessors
         */
        public ConsoleObject getObj() {
            return this.obj;
        }

        public ObjectState getState() {
            return this.state;
        }

        @Override
        public String toString() {
            return "[" + obj + ": " + state + "]";
        }

        public enum ConsoleObject {

            UNDEFINED_OBJ, RESERVED,
            /** Console keys */
            RESET, DISPLAY_MAR, SAVE, INSERT, RELEASE, START, SIE, SCE,
            /** Console toggle switches */
            POWER, SPARE, DISK, PARITY_CHECK, IO_CHECK, OVERFLOW_CHECK, SENSE_SWITCH_1, SENSE_SWITCH_2, SENSE_SWITCH_3, SENSE_SWITCH_4, EMERGENCY,
            /** Console dial */
            MAR_SELECTOR_DIAL,
            /** Card Reader events */
            LOAD, READ, PUNCH
        }

        public enum ObjectState {

            UNDEFINED_STATE, NA,
            /** Toggle switches */
            OFF, ON,
            /** Console keys */
            PRESSED,
            /** MAR selector dial positions */
            IR_1, IR_2, IR_3, OR_1, OR_2, OR_3, OR_4, OR_5, PR_1, PR_2, PR_3, CR_1
        }
    }


    /* -------------------------------------------------------------------- */
    /**
     * Subclass CyclerMessage:
     */
    public abstract class CyclerMessage extends Message {
        CyclerMessage() {
            super();
        }
    }

    public static class LoadCyclerMessage extends CyclerMessage {

        LoadCyclerMessage() {
            super();
        }

        @Override
        public void process() {
            try {
                Cycler.processLoadMessage();
            } catch (CheckStop ex) {
                Logger.getLogger(Message.class.getName()).log(Level.SEVERE, null, ex);
            } catch (BugStop ex) {
                Logger.getLogger(Message.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * Subclass CardReaderMessage:
     */
    public static class CardReaderMessage extends Message {

        byte[] card;
        boolean lastCardIndicator;

        public CardReaderMessage(byte[] card, boolean lc) {
            super();
            this.card = card;
            this.lastCardIndicator = lc;
        }

        @Override
        public void process() {
            Cycler.processCardReadMessage();
        }

        public byte[] getCard() {
            return card;
        }

        public boolean isLastCard() {
            return lastCardIndicator;
        }
    }

    /* -------------------------------------------------------------------- */
    /**
     * Subclass CardPunchMessage: this is sent FROM the punch TO the CPU
     * to acknowledge that the buffer has been accepted and the CPU may now
     * resume.
     */
    public static class CardPunchMessage extends Message {

        PunchMessage message;

        public CardPunchMessage(PunchMessage m) {
            super();
            message = m;
        }

        @Override
        public void process() {
        }

        public PunchMessage getPunchMessage() {
            return message;
        }

        public enum PunchMessage {

            BUFFER_ACCEPTED
        }
    }
}

4 个答案:

答案 0 :(得分:3)

这里没有错误。我刚刚成功地运行了它。

编辑: 你的所有类都是Message的内部类。这就是问题(我希望这不是故意的)。

答案 1 :(得分:1)

查看priority

Java类按以下顺序实例化:

(在上课时间)  按顺序的静态成员和静态初始化程序块的初始化程序     宣言。

(在每个新对象上)

  1. 为构造函数参数创建局部变量
  2. 如果构造函数以调用另一个构造函数开始 class,评估参数并递归到上一步。所有步骤 已完成该构造函数,包括进一步的递归 构造函数调用,然后继续。
  3. 如果上面没有构造超类,则构造 超类(如果未指定,则使用no​​-arg构造函数)。像#2一样, 完成超类的所有这些步骤,包括构建 在继续之前,它是超类。
  4. 实例变量和非静态初始化程序块的初始化程序,in 声明的顺序。
  5. 构造函数的其余部分。
  6. 此外,Odd situation for "cannot reference this before supertype constructor has been called"

答案 2 :(得分:1)

public abstract class CyclerMessage

与上面的其他内部类相反,未声明 static - 为什么?

您是否测试了如果将其声明为静态会发生什么?我不想知道是否会修复“无法引用”错误

public static abstract class CyclerMessage

答案 3 :(得分:0)

super()失败有3个原因,其中一个原因是你的超类没有no-arg构造函数,这是 NOT 的情况,另一个是{ {1}} NOT 是构造函数中的第一行,我认为是这种情况。 @EdC建议的另一个是你的超类构造函数对类不可见。