当前位置: 首页 > 知识库问答 >
问题:

Java:私有内部类合成构造函数[复制]

楚泳
2023-03-14

我有一个外部类,它有一个私有内部类。

在我的外层类方法中,我按如下方式实例化内部类:

Outer outer = new Outer();
Inner inner = outer.new Inner();

编译器将此代码转换为:

Outer outer = new Outer();
Inner inner = new Inner(outer, null);

使用反射显示内部类具有以下合成构造函数:

private Outer$Inner(Outer)
Outer$Inner(Outer,Outer$Inner)

由于internal类是private,编译器向其添加private构造函数,因此没有人可以实例化该类。但是显然,Outer类应该能够实例化它,因此编译器添加了另一个包私有构造函数,该构造函数反过来调用私有构造函数。另外,由于包私有构造函数的名称中有$,所以普通Java代码不能调用它。

问题:为什么要合成一个私有构造函数和一个包私有构造函数?为什么不只合成包私有构造函数并使用它呢?

共有3个答案

曾泳
2023-03-14

最可能的答案是尊重您在源代码中声明的内容。这样做仍然允许在声明私有构造函数时通过反射使用它。

这也避免了检查私有构造函数是否在内部类中实际调用。

洪照
2023-03-14

这不是一个答案,我认为斯布里奇已经很好地涵盖了这一点。这只是一个产生您描述的行为的工作示例:

public class Outer {
    private class Inner {
    }

    public static void main(String[] args) {
        printConstructors();

        //only one constructor is printed but two would appear if you 
        //uncommented the line below

        //new Outer().new Inner();
    }

    private static void printConstructors() {
        Constructor[] constructors = Outer.Inner.class.getDeclaredConstructors();
        for (Constructor c : constructors) {
            System.out.println(c.toGenericString());
        }
    }
}
应和光
2023-03-14

如果你像这样写代码,

public class Outer {
      private class Inner {}
}

您将注意到,只有一个构造函数private Outer$Inner(Outer)

JLS第8.8.9节要求该构造函数,该节规定,如果未定义构造函数,则必须生成默认构造函数,在这种情况下,默认构造函数必须是私有的,

在类类型中,如果该类被声明为public,则默认构造函数被隐式地赋予访问修饰符public(§6.6);如果该类被声明为受保护,则默认构造函数隐式地被赋予访问修饰符protected(§6.6);如果类被声明为private,则默认构造函数被隐式地赋予访问修饰符private(§6.6);否则,默认构造函数具有由无访问修饰符暗示的默认访问权限。

但是,当您使用如下代码实例化一个内部-外部的实例时,

public class Outer {
    private class Inner {}
        public String foo() {
            return new Inner().toString(); 
        }
}

编译器必须生成外部可以合法调用的构造函数(不能合法调用私有默认构造函数,因为它是私有的)。因此,编译器必须生成一个新的合成构造函数。根据JLS第13.1节,新构造必须是合成的

编译器引入的任何构造如果在源代码中没有相应的构造,则必须标记为合成,默认构造函数和类初始化方法除外。

第二个构造函数在源代码中没有相应的构造函数,因此这个新构造函数必须是合成的。仍然必须生成第一个私有构造函数,因为JLS需要一个私有默认构造函数。

 类似资料:
  • 问题内容: 我有一堂课。 在我的类方法中,我实例化该类,如下所示: 编译器将此代码转换为: 使用反射表明该类具有以下综合的构造函数: 由于该类是,因此编译器会将该构造函数添加到该类中,因此没有人可以实例化该类。但是很明显,该类应该能够实例化它,因此编译器添加了另一个包私有构造函数,后者又调用了私有构造函数。另外,由于package- private构造函数的名称中包含该名称,因此普通的Java代码

  • 我正在重构一个越来越大的android项目。运行lint使我能够在外部类和内部类之间访问JSME问题私有成员。考虑下面的例子 我得到消息了 应用问题解决方案会将源更改为 我现在有点困惑。直到现在,我还以为这个例子相当于 在这种情况下,我错了吗?还是这是棉绒的问题?

  • 问题内容: 我的代码中有内部类。我想授予对其实例的公共访问权限,但是只有外部类才可以创建此实例,就像在“私有”访问权限中一样。是否可以不做适当的小包装(或为每个这样的内部类创建公共接口)? (对不起,如果我的英语不好:P) 问题答案: 有可能的。将 内部类 声明为 public,但将其构造函数声明为private 。这样,您只能在封闭的类及其内部内部创建它,而不能从外部创建它。

  • 我有一个java类,它只有静态方法和字段,所以我不想为此创建任何对象。我可以从两个方面来理解, 创建类摘要 使用私有构造函数。 这两种方法哪一种更好?

  • 我有两个类:Date和Person Person有Date类的两个属性 案例1 类是与Person类分开的类。我有这段代码正常工作: 案例2:内部类(赋值要求) 我把作为Person的私有内部类 现在,上面的构造函数代码不再工作了。以下是错误消息: 说明资源路径位置类型由于某些中间构造函数调用人员,类型Person的封闭实例不可用。java/Wk03_Ch10_文件IO_Ch13_接口/Wk03_

  • 问题内容: 假设有一个类,其所有构造函数都声明为private。 例如。: 据我所知,将所有构造函数设为私有类似于将类“ This”声明为 final ,因此无法进行扩展。 但是,我收到的Eclipse消息给我的印象是这是可能的-可以扩展全构造函数私有类。看看这个: 当我尝试使用类似的方法扩展此类时 Eclipse给了我一个错误:“ 隐式超级构造函数This()对于默认构造函数不可见。必须定义一个