建设者总是要公开吗? [重复]

时间:2022-09-25 12:28:33

This question already has an answer here:

这个问题在这里已有答案:

My first question is -

我的第一个问题是 -

   class Explain() {
        public Explain() {
      }
   }

Should Constructor always declared as public?

构造函数是否应始终声明为公共?

What if I create a private constructor.

如果我创建一个私有构造函数怎么办?

I always seen constructors are implicitly public. So why private constructor is useful? Or is it not useful at all. Because nobody could ever call it, or never make an object(because of the private constructor) ! And that is my second question.

我一直认为施工人员是公开的。那么为什么私有构造函数有用呢?或者根本没用。因为没有人可以调用它,或者从不创建对象(因为私有构造函数)!这是我的第二个问题。

11 个解决方案

#1


67  

No, Constructors can be public, private, protected or default(no access modifier at all).

不,构造函数可以是public,private,protected或default(根本没有访问修饰符)。

Making something private doesn't mean nobody can access it. It just means that nobody outside the class can access it. So private constructor is useful too.

私有化并不意味着没有人可以访问它。这只意味着课堂上没有人可以访问它。所以私有构造函数也很有用。

One of the use of private constructor is to serve singleton classes. A singleton class is one which limits the number of objects creation to one. Using private constructor we can ensure that no more than one object can be created at a time.

私有构造函数的一个用途是提供单例类。单例类是将对象创建的数量限制为一个的类。使用私有构造函数,我们可以确保一次只能创建一个对象。

Example -

示例 -

public class Database {

    private static Database singleObject;
    private int record;
    private String name;

    private Database(String n) {
        name = n;
        record = 0;
    }

    public static synchronized Database getInstance(String n) {
        if (singleObject == null) {
            singleObject = new Database(n);
        }

        return singleObject;
    }

    public void doSomething() {
        System.out.println("Hello *.");
    }

    public String getName() {
        return name;
    }
}

More information about access modifiers.

有关访问修饰符的更多信息。

#2


9  

Yes , Constructors can have any access specifier/access modifier.

是的,构造函数可以具有任何访问说明符/访问修饰符。

Private constructors are useful for creating singleton classes.

私有构造函数对于创建单例类很有用。

Singleton - A singleton class is a class where only a single object can be created at runtime (per JVM) .

Singleton - 单例类是一个只能在运行时创建单个对象的类(每个JVM)。

A simple example of a singleton class is -

单例类的一个简单例子是 -

class Ex {
    private static Ex instance;
    int a;
    private Ex() {
        a = 10;
    }
    public static Ex getInstance() {
        if(instance == null) {
            instance = new Ex();
        }
        return instance;
    }
}

Note, for the above class, the only way to get an object (outside this class) is to call the getInstance() function, which would only create a single instance and keep returning that.

注意,对于上面的类,获取对象(在此类之外)的唯一方法是调用getInstance()函数,该函数只创建一个实例并继续返回该实例。

Also, note that this is not thread-safe.

另请注意,这不是线程安全的。

#3


7  

Constructors could be public, default or private and it all depends on what you want to do with it.

构造函数可以是公共的,默认的或私有的,这完全取决于你想用它做什么。

For example, if you are defining a Singleton class, you'd better hide (meaning making it private so that it is only available to the class where it belongs) the constructor to prevent other classes to instantiate your class at their will.

例如,如果要定义Singleton类,则最好隐藏(意味着将其设置为私有,以便它仅对其所属的类可用)构造函数,以防止其他类随意实例化您的类。

You may want to declare it default, let's say, for testing purposes so that test cases within the same package could access it.

您可能希望将其声明为默认值,例如,用于测试目的,以便同一个包中的测试用例可以访问它。

More detailed info could be found here

更详细的信息可以在这里找到

#4


5  

There is no rule that constructor to be public .Generally we define it public just because we would like to instantiate it from other classes too .

没有规则将构造函数公开。通常我们将它定义为public只是因为我们想要从其他类中实例化它。

Private constructor means,"i dont let anyone create my instance except me ". So normally you would do this when you like to have a singleton pattern.

私有构造函数意味着,“除了我,我不会让任何人创建我的实例”。所以通常你会喜欢有单身模式。

Following is the class in JDK which uses a private constructor .

以下是JDK中使用私有构造函数的类。

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    // Don't let anyone else instantiate this class
    private Runtime() {
    }
}

#5


5  

No,Constructors can use any access modifier, including private. (A private constructor means only code within the class itself can instantiate an object of that type, so if the private constructor class wants to allow an instance of the class to be used, the class must provide a static method or variable that allows access to an instance created from within the class.)

不,构造函数可以使用任何访问修饰符,包括私有。 (私有构造函数意味着只有类本身的代码可以实例化该类型的对象,因此如果私有构造函数类想要允许使用该类的实例,则该类必须提供允许访问的静态方法或变量从类中创建的实例。)

Example

class Alpha {
   static String s = " ";
   protected Alpha() { s += "alpha "; }
 }
 class SubAlpha extends Alpha {
   private SubAlpha() { s += "sub "; }
 }
 public class SubSubAlpha extends Alpha {
   private SubSubAlpha() { s += "subsub "; }
   public static void main(String[] args) {
     new SubSubAlpha();
     System.out.println(s);
   }
 }

Output of above program will be

上述计划的输出将是

alpha subsub

alpha子文章

#6


4  

Constructors can have all kind of access modifiers. The usage of different access modifier on constructors are different.

构造函数可以拥有所有类型的访问修饰符。在构造函数上使用不同的访问修饰符是不同的。

You make a constructor public if you want the class to be instantiated from any where.

如果希望从任何位置实例化类,则可以将构造函数设置为public。

You make a constructor protected if you want the class to be inherited and its inherited classes be instantiated.

如果希望继承该类并实例化其继承的类,则可以使构造函数受到保护。

You make a constructor private if you want the class to be instantiated just from its own members usually a static block or static method. It means that you take control of instantiating the class and apply some rule on instantiation. Example of usage of private constructor is singleton design pattern.

如果您希望仅从其自己的成员(通常是静态块或静态方法)实例化类,则可以将构造函数设置为私有。这意味着您可以控制实例化类并在实例化上应用一些规则。私有构造函数的使用示例是单例设计模式。

#7


4  

I agree with the previous answers that a Singleton is a good example of a class having a private constructor. I would though recommend a different implementation: a thread safe Singleton:

我同意以前的答案,Singleton是一个拥有私有构造函数的类的一个很好的例子。我会推荐一个不同的实现:一个线程安全的Singleton:

/**
 * Thread safe singleton
 */
public class Singleton {

    private static volatile Singleton instance = null;

    /**
     * Private constructor
     */
    private Singleton() {
    }

    /**
     * Gets the Instance of the Singleton in a thread safe way.
     * @return
     */
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Using a singleton in a thread safe way will safe you a lot of pain in parallel code.

以线程安全的方式使用单例将在并行代码中避免很多痛苦。

#8


3  

A constructor has to be at least protected or even private while creating, for example, custom factory classes, like:

在创建自定义工厂类时,构造函数必须至少受到保护,甚至是私有的,例如:

public final class MyFactory {
  private MyFactory(){} // this one prevents instances of your factory
}

public static void doSomething(){} // access that with MyFactory.doSomething

Note that this is only one example showing when a constructor shouldn't be public.

请注意,这只是一个示例,显示构造函数何时不应该是公共的。

#9


1  

Most of these answers refer to a singleton or factory class. Another time a private constructor appears is (for example) in the java.lang.Math class, where everything is static and no one should ever call the constructor (including the class itself). By having the private constructor, you prevent anyone outside the class from calling the constructor. (This doesn’t prevent someone inside the class from calling the constructor, but then they’re breaking their own rule.)

这些答案大多指的是单身人士或工厂阶级。另一次出现私有构造函数(例如)在java.lang.Math类中,其中一切都是静态的,没有人应该调用构造函数(包括类本身)。通过使用私有构造函数,可以防止类外的任何人调用构造函数。 (这并不妨碍类中的某个人调用构造函数,但是他们违反了自己的规则。)

#10


1  

Others have noted that constructors may have access modifiers; an aspect not yet mentioned is that the aspect modifiers on a constructor control two very different aspects of construction, but do not allow them to be controlled separately:

其他人已经注意到构造函数可能具有访问修饰符;尚未提及的一个方面是构造函数上的方面修饰符控制构造的两个非常不同的方面,但不允许它们单独控制:

  1. Who is allowed to create instances of ClassName and what constructors are they allowed to use.
  2. 允许谁创建ClassName的实例以及允许使用哪些构造函数。
  3. Who is allowed to create extensions of ClassName and what constructors are they allowed to use.
  4. 允许谁创建ClassName的扩展以及允许使用哪些构造函数。

Both Java and .NET require that the answers to those two questions go together; if a class isn't final (or sealed) and allows a constructor to be used by outside code to create new instances, then outside code will also have total freedom to use that same constructor to create derived types.

Java和.NET都要求将这两个问题的答案放在一起;如果一个类不是最终的(或密封的)并且允许外部代码使用构造函数来创建新实例,那么外部代码也可以完全*地使用相同的构造函数来创建派生类型。

In many cases, it may be appropriate for a class to have only package-private (internal) constructors, but expose public methods that return new instances. Such an approach might be used if one were designing a type like String from scratch; a package including String could define it as an abstract type but include concrete derived types like AsciiString and UCS16String which store their content as a byte[] and Char[], respectively; methods that return String could then return one of the derivatives depending upon whether the string contained characters outside the ASCII range. If neither String nor any derived types expose any constructors outside its package, and all derived types within the package behave as a string would be expected to behave, then code which receives a reference of type String could expect it to behave sanely as a string (e.g. guaranteeing that any observations about its value will forevermore remain true). Exposing constructors outside the package, however, would make it possible for derived types to behave in weird and bizarre fashion (e.g. changing their contents after they've been examined and validated).

在许多情况下,类可能只适用于包 - 私有(内部)构造函数,但是公开返回新实例的公共方法。如果从头开始设计类似String的类型,可以使用这种方法;包含String的包可以将它定义为抽象类型,但包括具体的派生类型,如AsciiString和UCS16String,它们分别将它们的内容存储为byte []和Char [];返回String的方法然后可以返回其中一个派生词,具体取决于字符串是否包含ASCII范围之外的字符。如果String和任何派生类型都没有公开其包之外的任何构造函数,并且包中的所有派生类型都表现为行为,那么接收类型为String的引用的代码可以期望它作为字符串表现得很好(例如,保证对其价值的任何观察将永远保持真实)。然而,将构造函数暴露在包之外将使得派生类型可以以奇怪和奇怪的方式表现(例如,在它们被检查和验证之后改变它们的内容)。

From a syntactical perspective, being able to say Fnord foo = new Fnord(123); is a little nicer than having to say Fnord foo = Fnord.Create(123);, but a class Fnord that requires the latter syntax can maintain much better control over the object-creation process.

从语法的角度来看,能够说Fnord foo = new Fnord(123);比Fnord foo = Fnord.Create(123);更好一点,但是需要后一种语法的类Fnord可以更好地控制对象创建过程。

#11


0  

The simple explanation is if there is no constructor in a class, the compiler automatically creates a default constructor.

简单的解释是,如果类中没有构造函数,编译器会自动创建默认构造函数。

The constructor is not always declared as public, it can also be private, protected, or default.

构造函数并不总是声明为public,也可以是private,protected或default。

The private constructors prevent a class from fully and clearly expressed/represented by its callers. In that case private constructors are useful. And if if we do not need our class to be sub-classed, we can use private constructors.

私有构造函数阻止类被其调用者完全清楚地表达/表示。在这种情况下,私有构造函数是有用的。如果我们不需要我们的类被分类,我们可以使用私有构造函数。

#1


67  

No, Constructors can be public, private, protected or default(no access modifier at all).

不,构造函数可以是public,private,protected或default(根本没有访问修饰符)。

Making something private doesn't mean nobody can access it. It just means that nobody outside the class can access it. So private constructor is useful too.

私有化并不意味着没有人可以访问它。这只意味着课堂上没有人可以访问它。所以私有构造函数也很有用。

One of the use of private constructor is to serve singleton classes. A singleton class is one which limits the number of objects creation to one. Using private constructor we can ensure that no more than one object can be created at a time.

私有构造函数的一个用途是提供单例类。单例类是将对象创建的数量限制为一个的类。使用私有构造函数,我们可以确保一次只能创建一个对象。

Example -

示例 -

public class Database {

    private static Database singleObject;
    private int record;
    private String name;

    private Database(String n) {
        name = n;
        record = 0;
    }

    public static synchronized Database getInstance(String n) {
        if (singleObject == null) {
            singleObject = new Database(n);
        }

        return singleObject;
    }

    public void doSomething() {
        System.out.println("Hello *.");
    }

    public String getName() {
        return name;
    }
}

More information about access modifiers.

有关访问修饰符的更多信息。

#2


9  

Yes , Constructors can have any access specifier/access modifier.

是的,构造函数可以具有任何访问说明符/访问修饰符。

Private constructors are useful for creating singleton classes.

私有构造函数对于创建单例类很有用。

Singleton - A singleton class is a class where only a single object can be created at runtime (per JVM) .

Singleton - 单例类是一个只能在运行时创建单个对象的类(每个JVM)。

A simple example of a singleton class is -

单例类的一个简单例子是 -

class Ex {
    private static Ex instance;
    int a;
    private Ex() {
        a = 10;
    }
    public static Ex getInstance() {
        if(instance == null) {
            instance = new Ex();
        }
        return instance;
    }
}

Note, for the above class, the only way to get an object (outside this class) is to call the getInstance() function, which would only create a single instance and keep returning that.

注意,对于上面的类,获取对象(在此类之外)的唯一方法是调用getInstance()函数,该函数只创建一个实例并继续返回该实例。

Also, note that this is not thread-safe.

另请注意,这不是线程安全的。

#3


7  

Constructors could be public, default or private and it all depends on what you want to do with it.

构造函数可以是公共的,默认的或私有的,这完全取决于你想用它做什么。

For example, if you are defining a Singleton class, you'd better hide (meaning making it private so that it is only available to the class where it belongs) the constructor to prevent other classes to instantiate your class at their will.

例如,如果要定义Singleton类,则最好隐藏(意味着将其设置为私有,以便它仅对其所属的类可用)构造函数,以防止其他类随意实例化您的类。

You may want to declare it default, let's say, for testing purposes so that test cases within the same package could access it.

您可能希望将其声明为默认值,例如,用于测试目的,以便同一个包中的测试用例可以访问它。

More detailed info could be found here

更详细的信息可以在这里找到

#4


5  

There is no rule that constructor to be public .Generally we define it public just because we would like to instantiate it from other classes too .

没有规则将构造函数公开。通常我们将它定义为public只是因为我们想要从其他类中实例化它。

Private constructor means,"i dont let anyone create my instance except me ". So normally you would do this when you like to have a singleton pattern.

私有构造函数意味着,“除了我,我不会让任何人创建我的实例”。所以通常你会喜欢有单身模式。

Following is the class in JDK which uses a private constructor .

以下是JDK中使用私有构造函数的类。

public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    // Don't let anyone else instantiate this class
    private Runtime() {
    }
}

#5


5  

No,Constructors can use any access modifier, including private. (A private constructor means only code within the class itself can instantiate an object of that type, so if the private constructor class wants to allow an instance of the class to be used, the class must provide a static method or variable that allows access to an instance created from within the class.)

不,构造函数可以使用任何访问修饰符,包括私有。 (私有构造函数意味着只有类本身的代码可以实例化该类型的对象,因此如果私有构造函数类想要允许使用该类的实例,则该类必须提供允许访问的静态方法或变量从类中创建的实例。)

Example

class Alpha {
   static String s = " ";
   protected Alpha() { s += "alpha "; }
 }
 class SubAlpha extends Alpha {
   private SubAlpha() { s += "sub "; }
 }
 public class SubSubAlpha extends Alpha {
   private SubSubAlpha() { s += "subsub "; }
   public static void main(String[] args) {
     new SubSubAlpha();
     System.out.println(s);
   }
 }

Output of above program will be

上述计划的输出将是

alpha subsub

alpha子文章

#6


4  

Constructors can have all kind of access modifiers. The usage of different access modifier on constructors are different.

构造函数可以拥有所有类型的访问修饰符。在构造函数上使用不同的访问修饰符是不同的。

You make a constructor public if you want the class to be instantiated from any where.

如果希望从任何位置实例化类,则可以将构造函数设置为public。

You make a constructor protected if you want the class to be inherited and its inherited classes be instantiated.

如果希望继承该类并实例化其继承的类,则可以使构造函数受到保护。

You make a constructor private if you want the class to be instantiated just from its own members usually a static block or static method. It means that you take control of instantiating the class and apply some rule on instantiation. Example of usage of private constructor is singleton design pattern.

如果您希望仅从其自己的成员(通常是静态块或静态方法)实例化类,则可以将构造函数设置为私有。这意味着您可以控制实例化类并在实例化上应用一些规则。私有构造函数的使用示例是单例设计模式。

#7


4  

I agree with the previous answers that a Singleton is a good example of a class having a private constructor. I would though recommend a different implementation: a thread safe Singleton:

我同意以前的答案,Singleton是一个拥有私有构造函数的类的一个很好的例子。我会推荐一个不同的实现:一个线程安全的Singleton:

/**
 * Thread safe singleton
 */
public class Singleton {

    private static volatile Singleton instance = null;

    /**
     * Private constructor
     */
    private Singleton() {
    }

    /**
     * Gets the Instance of the Singleton in a thread safe way.
     * @return
     */
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Using a singleton in a thread safe way will safe you a lot of pain in parallel code.

以线程安全的方式使用单例将在并行代码中避免很多痛苦。

#8


3  

A constructor has to be at least protected or even private while creating, for example, custom factory classes, like:

在创建自定义工厂类时,构造函数必须至少受到保护,甚至是私有的,例如:

public final class MyFactory {
  private MyFactory(){} // this one prevents instances of your factory
}

public static void doSomething(){} // access that with MyFactory.doSomething

Note that this is only one example showing when a constructor shouldn't be public.

请注意,这只是一个示例,显示构造函数何时不应该是公共的。

#9


1  

Most of these answers refer to a singleton or factory class. Another time a private constructor appears is (for example) in the java.lang.Math class, where everything is static and no one should ever call the constructor (including the class itself). By having the private constructor, you prevent anyone outside the class from calling the constructor. (This doesn’t prevent someone inside the class from calling the constructor, but then they’re breaking their own rule.)

这些答案大多指的是单身人士或工厂阶级。另一次出现私有构造函数(例如)在java.lang.Math类中,其中一切都是静态的,没有人应该调用构造函数(包括类本身)。通过使用私有构造函数,可以防止类外的任何人调用构造函数。 (这并不妨碍类中的某个人调用构造函数,但是他们违反了自己的规则。)

#10


1  

Others have noted that constructors may have access modifiers; an aspect not yet mentioned is that the aspect modifiers on a constructor control two very different aspects of construction, but do not allow them to be controlled separately:

其他人已经注意到构造函数可能具有访问修饰符;尚未提及的一个方面是构造函数上的方面修饰符控制构造的两个非常不同的方面,但不允许它们单独控制:

  1. Who is allowed to create instances of ClassName and what constructors are they allowed to use.
  2. 允许谁创建ClassName的实例以及允许使用哪些构造函数。
  3. Who is allowed to create extensions of ClassName and what constructors are they allowed to use.
  4. 允许谁创建ClassName的扩展以及允许使用哪些构造函数。

Both Java and .NET require that the answers to those two questions go together; if a class isn't final (or sealed) and allows a constructor to be used by outside code to create new instances, then outside code will also have total freedom to use that same constructor to create derived types.

Java和.NET都要求将这两个问题的答案放在一起;如果一个类不是最终的(或密封的)并且允许外部代码使用构造函数来创建新实例,那么外部代码也可以完全*地使用相同的构造函数来创建派生类型。

In many cases, it may be appropriate for a class to have only package-private (internal) constructors, but expose public methods that return new instances. Such an approach might be used if one were designing a type like String from scratch; a package including String could define it as an abstract type but include concrete derived types like AsciiString and UCS16String which store their content as a byte[] and Char[], respectively; methods that return String could then return one of the derivatives depending upon whether the string contained characters outside the ASCII range. If neither String nor any derived types expose any constructors outside its package, and all derived types within the package behave as a string would be expected to behave, then code which receives a reference of type String could expect it to behave sanely as a string (e.g. guaranteeing that any observations about its value will forevermore remain true). Exposing constructors outside the package, however, would make it possible for derived types to behave in weird and bizarre fashion (e.g. changing their contents after they've been examined and validated).

在许多情况下,类可能只适用于包 - 私有(内部)构造函数,但是公开返回新实例的公共方法。如果从头开始设计类似String的类型,可以使用这种方法;包含String的包可以将它定义为抽象类型,但包括具体的派生类型,如AsciiString和UCS16String,它们分别将它们的内容存储为byte []和Char [];返回String的方法然后可以返回其中一个派生词,具体取决于字符串是否包含ASCII范围之外的字符。如果String和任何派生类型都没有公开其包之外的任何构造函数,并且包中的所有派生类型都表现为行为,那么接收类型为String的引用的代码可以期望它作为字符串表现得很好(例如,保证对其价值的任何观察将永远保持真实)。然而,将构造函数暴露在包之外将使得派生类型可以以奇怪和奇怪的方式表现(例如,在它们被检查和验证之后改变它们的内容)。

From a syntactical perspective, being able to say Fnord foo = new Fnord(123); is a little nicer than having to say Fnord foo = Fnord.Create(123);, but a class Fnord that requires the latter syntax can maintain much better control over the object-creation process.

从语法的角度来看,能够说Fnord foo = new Fnord(123);比Fnord foo = Fnord.Create(123);更好一点,但是需要后一种语法的类Fnord可以更好地控制对象创建过程。

#11


0  

The simple explanation is if there is no constructor in a class, the compiler automatically creates a default constructor.

简单的解释是,如果类中没有构造函数,编译器会自动创建默认构造函数。

The constructor is not always declared as public, it can also be private, protected, or default.

构造函数并不总是声明为public,也可以是private,protected或default。

The private constructors prevent a class from fully and clearly expressed/represented by its callers. In that case private constructors are useful. And if if we do not need our class to be sub-classed, we can use private constructors.

私有构造函数阻止类被其调用者完全清楚地表达/表示。在这种情况下,私有构造函数是有用的。如果我们不需要我们的类被分类,我们可以使用私有构造函数。