IIOException如何没有no-arg构造函数?

时间:2014-07-10 06:44:18

标签: java inheritance constructor arguments

假设我们在文件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
{
}

3 个答案:

答案 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)
    {
    }
}