【问题标题】:Java Class Constructor Issue [closed]Java类构造函数问题[关闭]
【发布时间】:2014-11-20 13:59:55
【问题描述】:

什么是构造函数的默认类型,例如公共/私人/抽象等。

我们可以改变java中构造函数的类型吗?

当我将构造函数创建为私有时,它为什么不允许访问该类?

【问题讨论】:

  • 你认为“私人”是什么意思?
  • Private 表示类的访问修饰符。

标签: java


【解决方案1】:

是的,您可以在 java 中更改构造函数的类型。 默认情况下,构造函数不是公共的。对于具有默认访问修饰符的类,构造函数访问也是默认的。对于内部类,类可以具有任何访问修饰符,因此构造函数也将具有相同的访问修饰符,除非我们定义构造函数不同的访问修饰符

private 用于单例的情况。请注意,如果您这样做,则无法从类外部实例化该类。

对于私有构造函数,您可以执行类似单例的操作

public class Foo {
    private Foo foo;
    private Foo(){} // default you may not see it in the editor but is provided by complier
    public static Foo getInstance(){ 
        if(foo==null)
           foo=new Foo();
        return foo;
    }
}

【讨论】:

  • 默认情况下,构造函数是不公开的。对于具有默认访问修饰符的类,构造函数访问也是默认的。对于内部类,该类可以具有任何访问修饰符,因此构造函数也将具有相同的访问修饰符访问修饰符,除非我们使用不同的访问修饰符定义构造函数
【解决方案2】:

构造函数的默认类型是什么?公共/私人/抽象等? 对于default constructor,这取决于类的可访问性,如果使用public 声明类,则默认构造函数将是公共的,如果将类声明为受保护的,则默认构造函数将受到保护。
当我创建构造函数时作为私有它不允许访问该类,为什么? 因为构造函数在类外是不可见的。

【讨论】:

  • 但是当我们创建一个参数化的构造函数时,我们会从类外部调用它。
  • @Altmish 当您创建构造函数时,您可以自行决定要应用哪种类型的访问修饰符(公共/私有/等)。
【解决方案3】:

如果你有一个构造函数并且它是私有的,那么这意味着没有人可以创建你的类的对象。但是有一种方法可以获取类的对象,即使用单音。

public class Foo {

    private static Foo foo;

    private Foo() { }

    public static Foo getInstance() {
        if (foo == null) {
            foo = new Foo();
        }
        return foo;
    }
}

【讨论】:

  • 你的第一句话不太准确。如果您有 一个 构造函数并且它是私有的,则外部类无法创建该类的对象。但是一个类可以有多个构造函数,其中一个是私有的,其他的调用它。
  • ajb 我已经更新了我的帖子,谢谢
【解决方案4】:

您可以通过以下方式定义您的构造函数:

  • public A() — 这意味着每个其他类都可以创建一个 A 实例。
  • protected A() — 受保护的访问意味着它只能由 A 实例或其子类访问,但前提是该子类涉及其父类的实现。 See this post
  • private A() — 这意味着除了A 本身 嵌套或封装类之外没有其他类可以调用构造函数。它通常用于创建单例;使用静态方法创建对象:

    public class A {
    
        private static A instance;
    
        // Make constructor private
        private A() { }
    
        public static A getInstance() {
            // Create an instance if it is not yet created.
            if (A.instance == null) {
                A.instance = new A();
            }
            return A.instance;
        }
    }
    
  • A() — 如果省略了访问修饰符(如 public 或 private),则称为 package-private。包私有构造函数只能由同一包中的类或该类的子类访问。

There is a table你可能会觉得有用:

             |Class | Package | Subclass | World
public       | Y    | Y       | Y        | Y
protected    | Y    | Y       | Y        | N
no modifier  | Y    | Y       | N        | N
private      | Y    | N       | N        | N

注意no modifier表示你没有声明修饰符,也就是省略它。

【讨论】:

  • 这实际上并不完全正确。如果类A 嵌套在另一个类B 中,即使A 的所有构造函数都是私有的,B 也可以创建A 的实例。 See here
  • @IngoBürk 没错;感谢您的关注。我已经更新了答案。
【解决方案5】:

如果你编写一个没有访问修饰符的构造函数:

public class MyClass {

    MyClass (int param) {
        // constructor code
    }

}

那么可访问性是包私有,与没有访问修饰符的任何方法的可访问性相同。 (JLS 6.6.1:“一个没有访问修饰符的类成员或构造函数隐式地具有包访问权限。”)所以这是构造函数的默认“类型”(实际上是默认可访问性)。在这个例子中,package-private 构造函数意味着您可以使用来自同一个包中的类的new MyClass(10),但不能在包外使用。

您可以像使用任何其他方法一样添加可访问性修饰符:publicprivateprotected。但是,根据JLS 8.8.3,您不能使用其他修饰符,例如abstract

如果你把它设为private,那么构造函数就不能在类之外使用(或者,对于嵌套类,在包含它的顶级类之外),但它可以在内部使用 em>类。这意味着你的类可以定义一个静态工厂方法,它不是真正的构造函数,而是用于构造类的对象:

public class MyClass {

    private MyClass(int param) { ... }

    public static MyClass CreateObject(String something) {
        // stuff
        return new MyClass(n);
    }

}

单例类也使用类似的习惯用法,其中方法像工厂方法一样返回类的实例,但也确保只创建一个实例。

私有构造函数也可以被其他构造函数使用:

public class MyClass {

    private MyClass(boolean isString, String stringParam, int intParam) {
        // stuff
    }

    public MyClass(String stringParam) {
        this(true, stringParam, -1);
    }

    public MyClass(int intParam) {
        this(false, null, intParam);
    }

}

如果你声明了一个private 构造函数并且不在类的任何地方使用它,这是一个经常用来定义一个只用于提供静态实用方法的类的习惯用法。可以调用静态方法,但不能创建类的实例。

【讨论】:

  • 另外,这里:如果是嵌套类,则私有构造函数可以在该类之外使用。 See this
  • @IngoBürk 忘记了那个案例...已编辑。
猜你喜欢
  • 2011-06-08
  • 2019-04-15
  • 1970-01-01
  • 2018-05-06
  • 1970-01-01
  • 2023-03-03
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多