假设我们在文件NoArgConstructorClass.java中有一个NoArgConstructorClass类
/* first example */
import javax.imageio.IIOException;
public class NoArgConstructorClass
{
public static void main(String[] args)
{
NoArgConstructorClass n = new NoArgConstructorClass();
IIOException e = new IIOException();
}
}
编译时的这段代码会产生错误:没有为IIOException找到合适的构造函数。
由于IIOException应该有一个no-arg构造函数(由compilator添加),如何使IIOException没有no-arg构造函数?
/** second example, showing that ClassB inherits a no-arg constructor from Object */
/** put in ConstructorChain.java */
public class ConstructorChain
{
public static void main(String[] args)
{
ClassB b = new ClassB();
}
}
/** put in ClassA.java */
public class ClassA
{
public ClassA()
{
System.out.println("Class A");
}
}
/** put in ClassB.java */
public class ClassB
extends ClassA
{
}
答案 0 :(得分:2)
Q值。编译时的这段代码会产生错误:没有为IIOException找到合适的构造函数。
如果查看IIOException
的文档,可以看到它没有默认(no-arg)构造函数。它有2个构造函数,都是参数化的(单参数和双参数)。这就是当您尝试使用no-arg构造函数创建IIOException
实例时出现编译错误的原因。
Q值。既然IIOException应该从Object继承一个no-arg构造函数,那么如何使IIOException没有no-arg构造函数呢?
它不继承no-arg构造函数。当一个类被继承时,你可以使用super()
添加对它的超类构造函数的调用,或者如果你不这样做,编译器就会这样做。所以IIOException
的构造函数看起来像这样。
public IIOException(String message) {
// if the below line is not present, the compiler adds it
super(); // This calls the parent class (IOException) constructor and since there is a no-arg constructor there, its perfectly valid
... // other code
}
我现在重新阅读你的问题两次,我认为你正在把编译器添加一个默认的no-arg构造函数作为从父类继承的构造函数。
如JLS-8.8.9中所述(感谢链接的OP),
如果你有一个没有构造函数的类(有或没有arg),编译器会自己添加一个默认的无参数构造函数。 但是如果指定带有arg的构造函数并且未指定no-arg构造函数,则编译器不会向类中添加默认的无参数构造函数。让我举一个例子。
class A {}
您可以使用A
实例化类A a = new A()
,因为即使您未指定任何构造函数,也会向该类添加默认的无参数构造函数。
但如果你的班级看起来像这样,
class A {
public A(int b) {
}
}
在这种情况下,您有一个参数构造函数。您现在可以仅使用此构造函数来实例化您的类,因为编译器不会向其添加默认的无参数构造函数,因为它已经有一个构造函数(带有一个参数)。因此,A a = new A(1)
会起作用,而A a = new A()
则不起作用。
如果您希望能够创建这样的实例A a = new A()
,那么您需要向您的类显式添加一个无参数构造函数,就像这样
class A {
public A(int b) { // single argument constructor
}
public A() { // no argument constructor
}
}
答案 1 :(得分:2)
如果您使用下面的代码而不是示例2,那么它将产生编译错误。 IIOException是这样的工作。所以你得到了例1中的编译错误。
public class ConstructorChain
{
public static void main(String[] args)
{
ClassB b = new ClassB();
}
}
class ClassA
{
public ClassA()
{
System.out.println("Class A");
}
}
/** put in ClassB.java */
class ClassB
extends ClassA
{
ClassB(String str)
{
}
}
答案 2 :(得分:0)
如果一个类没有构造函数(如在ClassB中),那么根据Java语言规范8.8.9 "Default constructor": “如果一个类不包含构造函数声明,则默认构造函数没有形式参数且没有throws子句被隐式声明。”
因此,如果该类至少有一个构造函数,那么它应该拥有它自己的no-arg构造函数的声明来实际拥有它。
因此,如果ClassB至少有一个构造函数
/** put in ClassB.java */
public class ClassB
extends ClassA
{
public ClassB(String s)
{
}
}
然后它将没有no-arg构造函数,除非它是明确定义的:
/** put in ClassB.java */
public class ClassB
extends ClassA
{
public ClassB()
{
}
public ClassB(String s)
{
}
}