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

Java私有构造函数可见性

邹宏峻
2023-03-14

我试图理解为什么在谈到构造函数时,类成员的可访问性之间存在差异。

考虑下面的例子:

class A {
  static class B {  
    private B(String s) {}
    private void foo() {}
  }
  static class C extends B {
    public C(String s) {
      super(s); // call B(String), which is private, and obviously accessible
    }
    void bar() {
      foo(); // compilation error (symbol unknown), as B.foo() is private
    }
  }
}

A的私有成员作为私有成员,不应从B访问。对于字段和方法,情况确实如此,但构造函数似乎没有遵循相同的规则。

从JLS-8(6.6.1.确定可访问性)中,我们可以阅读:

[...]

引用类型的成员(类、接口、字段或方法)或类类型的构造函数只有在类型可访问且声明该成员或构造函数允许访问时才可访问:

>

  • [……]

    否则,成员或构造函数被声明为私有,并且只有当访问发生在包含成员或构造函数声明的顶级类(§7.6)的主体中时,才允许访问。

    有人能解释一下为什么构造函数可以从C访问,即使它被声明为私有的

  • 共有3个答案

    巩子实
    2023-03-14

    Foo()方法在C类中不可访问,因为foo()方法是私有的,私有方法不能继承到基类。

    对于构造函数,永远不会继承构造函数。此外,我编译了以下代码:

     class Vehicle{  
            int speed=50;  
            private Vehicle()
            {
               System.out.println("Private Vehicle constructor");
            }
        } 
        public class Bike4 extends Vehicle{  
            int speed=100;   
        Bike4()
        {
            super();
             System.out.println("Hi I n constructor");
        }
      void display(){  
       System.out.println(super.speed);//will print speed of Vehicle now  
      }  
      public static void main(String args[]){  
       Bike4 b=new Bike4();  
       b.display();  
    
    }  
    }  
    

    并获得编译时间错误:车辆()在车辆超级()中有私有访问;^这清楚地表明不能使用超级访问私有构造函数。如果我们能够初始化或访问私有构造函数,那么创建私有构造函数的意义是什么。

    麹浩瀚
    2023-03-14

    所以这里的诀窍可能是:

    您无法访问foo,因为它被声明为私有,所以您不会在C中继承它。

    但是,正如注释中所指出的,您可以访问super。foo() 因为super指的是在同一顶级类中声明的类型(请参见JLS 6.6.1)。

    然后诀窍是调用超级(s)可以被视为调用超级。

    薛钧
    2023-03-14

    方法foo()是私有的,因此您不能继承它,也不能直接从C调用它。

    然而,您可以从B中看到私有方法和构造函数,因为所有内容都声明在同一个包含类中,并使用超级访问它们,这就是为什么超级()工作。同样,您可以使用super.foo()访问foo

    请注意,您可以在C中重新定义新的foo方法,但此方法不会覆盖B.foo()

     类似资料:
    • 问题内容: 构造函数可以私有吗?私有构造函数有什么用? 问题答案: 是的,构造函数可以是私有的。有不同的用途。一种这样的用法是用于单例设计反模式,我建议你不要使用它。另一个更合理的用法是委派构造函数。你可以让一个构造函数接受很多不同的选项,而这些选项实际上是实现细节,因此你将其设为私有,但是其余的构造函数将委托给它。 作为委派构造函数的示例,以下类允许你保存值和类型,但仅允许你对类型的子集进行保存

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

    • 问题内容: 构造函数可以是私有的吗?私有构造函数有何用处? 问题答案: 是的,构造函数可以是私有的。这有不同的用途。一个这样的用途是用于singleton设计反模式,我建议您不要使用它。另一个更合法的用法是委托构造函数;您可以有一个构造函数,它接受许多不同的选项,这实际上是一个实现细节,所以您将其设为私有,但剩余的构造函数将其委托给它。 作为委托构造函数的一个例子,下面的类允许您保存一个值和一个类

    • 问题内容: 在春季,bean的类可能没有公共构造函数,而只有私有构造函数吗?创建bean时会调用此私有构造函数吗?谢谢。 问题答案: 是的,Spring可以调用私有构造函数。如果找到具有正确参数的构造函数,无论可见性如何,它将使用反射将其构造函数设置为可访问的。

    • 在经历冬眠3时。x文档我知道我们也可以为具有私有可见性的POJO声明一个无arg构造函数,但文档说它有限制: 无参数构造函数是所有持久类的要求;Hibernate必须使用Java反射为您创建对象。构造器可以是私有的,但是在没有字节码插装的情况下,运行时代理生成和有效的数据检索需要包或公共可见性。 我不熟悉Hibernate,我试图了解何时使用运行时代理,何时使用字节码,以及这在Hibernate中

    • 问题内容: 为什么将只有私有构造函数的类标记为final是一个好习惯?我的猜测是,要让其他程序员知道它不能被子类化。 问题答案: 将类定为final具有一些(小的)性能提升,因为JIT编译器可以内联该类的功能。我不知道这是否符合“良好做法”的要求,但是我看到了好处。