为什么我在 Java 构造函数中对 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 <[email protected]>
* @author Chap Harrison <[email protected]>
*/
//
//
// 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
}
}
}
I have:
- an abstract Message class,
- an abstract CustomMessage extending Message,
- a concrete SpecializedCustomMessage class extending CustomMessage,
as shown below, and I'm having trouble with the concrete class's constructor's call to super(). I've left out many details that I assume are irrelevant to the error I'm encountering. Is there a problem with having two levels of abstraction before deriving a concrete class?
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();
}
}
Edit: as requested, the entire file. Search for 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 <[email protected]>
* @author Chap Harrison <[email protected]>
*/
//
//
// 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
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里没有错误。我刚刚运行成功了。
编辑:
您的所有类都是 Message 的内部类。这就是问题所在(我希望这不是故意的)。
There is no error here. I just ran it successfully.
EDIT:
All of your classes are inner classes of Message. That's the problem (I hope this is not intentional).
与上面的其他内部类相反,没有声明静态 - 为什么?
您是否测试过如果将其声明为静态会发生什么?我不知道这是否会修复“无法引用”错误
as opposed to other inner classes above is not declared static - why?
Did you test what happens if you declare it static? I wouldn't wonder if that will fix "cannot reference" error
查看
优先级
。Java 类按以下顺序实例化:(
在类加载时)
0. 静态成员和静态初始化块的初始值设定项(按顺序)
的声明。
(在每个新对象上)
类,评估参数并递归到上一步。所有步骤
为该构造函数完成,包括进一步递归
在继续之前调用构造函数。
超类(如果未指定,则使用无参数构造函数)。就像#2一样,
完成超类的所有这些步骤,包括构建
在继续之前,它是超一流的。
声明顺序。
另外,“无法引用”的奇怪情况this 在调用超类型构造函数之前"
Look at
priority
.Java classes are instantiated in the following order:
(at classload time)
0. initializers for static members and static initializer blocks, in order
of declaration.
(at each new object)
class, evaluate the arguments and recurse to previous step. All steps
are completed for that constructor, including further recursion of
constructor calls, before continuing.
the superclass (using the no-arg constructor if not specified). Like #2,
go through all of these steps for the superclass, including constructing
IT'S superclass, before continuing.
order of declaration.
Also, Odd situation for "cannot reference this before supertype constructor has been called"
super()
失败的原因有 3 个,其中之一是您的超类没有无参数构造函数,而事实并非如此,另一个是super()
不是构造函数中的第一行,我认为是这样。 @EdC 建议的另一种方法是您的超类构造函数对该类不可见。There are 3 reasons why
super()
would fail, one of them is that your superclass does not have no-arg constructor, which is NOT the case, the other one being thatsuper()
is NOT the first line in your constructor, which I think is the case. Another one as suggested by @EdC would be that your super class constructor is not visible to the class.