可能重复:
在类中创建私有构造函数有什么用?
我们在哪里需要私人构造函数?我们如何实例化一个具有私有构造函数的类?
对实用程序类来说,常见的做法是为它们提供一个私有构造函数:
public final class UtilClass {
private UtilClass() {}
...
}
Run Code Online (Sandbox Code Playgroud)
但不幸的是,有些工具不喜欢私有构造函数.他们可能会警告它在类中没有被调用,它没有被测试覆盖,块不包含注释等.
如果您这样做,很多警告就会消失:
public enum UtilClass {;
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:除了对未来开发人员的无休止的仇恨之外,没有值的枚举和Java中的私有构造函数的类之间有什么重要的区别?
请注意,我并不是说Java枚举与具有公共静态最终字段的类相比有什么优势?.我不是在决定一系列事物应该是一堆常量还是一个枚举,我决定将一堆函数放在无构造函数的类或无值的枚举中.
另请注意,我实际上并不想这样做.我只想知道权衡作为一般语言知识的一部分.
例如,使用枚举会使用无用的方法污染自动完成UtilClass.values().还有哪些缺点?上升空间?
如果我有以下具有私有构造函数的case类,并且我无法访问companion对象中的apply-method.
case class Meter private (m: Int)
val m = Meter(10) // constructor Meter in class Meter cannot be accessed...
Run Code Online (Sandbox Code Playgroud)
有没有办法将case类与私有构造函数一起使用,但是在公开的伴随中保留生成的apply-method?
我知道两个选项之间没有区别(在我的例子中):
val m1 = new Meter(10)
val m2 = Meter(10)
Run Code Online (Sandbox Code Playgroud)
但我想禁止第一种选择.
- 编辑 -
令人惊讶的是以下工作(但实际上并不是我想要的):
val x = Meter
val m3 = x(10) // m3 : Meter = Meter(10)
Run Code Online (Sandbox Code Playgroud) 我有一个只有静态方法和字段的java类,所以我不希望为此创建任何对象.我可以通过两种方式实现这一点,
哪两个更好的方式?
我绝对记得在某个地方看到一个使用反射或其他东西这样做的例子.这与SqlParameterCollection用户无法创造的事情有关(如果我没有记错的话).不幸的是再也找不到了.
有人可以在这里分享这个技巧吗?并不是说我认为它是一种有效的开发方法,我只是对这样做的可能性非常感兴趣.
例如,我想声明一个类,但我希望客户端无法使用复制构造函数(或复制赋值运算符)
以下两个都不允许使用复制构造函数:
1.
class Track
{
public:
Track(){};
~Track(){};
private:
Track(const Track&){};
};
Run Code Online (Sandbox Code Playgroud)
2.
class Track
{
public:
Track(){};
~Track(){};
Track(const Track&)=delete;
};
Run Code Online (Sandbox Code Playgroud)
其中一种方式"比其他方式更正确"还是相同?有副作用吗?
//Does not compile with both the above ways
int main()
{
Track l;
Track p(l);
}
Run Code Online (Sandbox Code Playgroud) 我想在宏中使用私有构造函数.此示例是一个正整数,但基本模式不仅可以用于其他数字类型(如偶数),还可以用于字符串派生类型(如电子邮件地址或目录名称).通过使构造函数为私有,用户被拒绝制作非法类型的机会.我有以下代码:
object PosInt
{
import language.experimental.macros
import reflect.runtime.universe._
import reflect.macros.Context
def op(inp: Int): Option[PosInt] = if (inp > 0) Some(new PosInt(inp)) else None
def apply(param: Int): PosInt = macro apply_impl
def apply_impl(c: Context)(param: c.Expr[Int]): c.Expr[PosInt] =
{
import c.universe._
param match {
case Expr(Literal(i)) if (i.value.asInstanceOf[Int] > 0) =>
case Expr(Literal(i)) if (i.value.asInstanceOf[Int] == 0) => c.abort(c.enclosingPosition, "0 is not a positive integer")
case Expr(Literal(i)) => c.abort(c.enclosingPosition, "is not a positive integer")
case _ => c.abort(c.enclosingPosition, "Not a Literal")
} …Run Code Online (Sandbox Code Playgroud) 如何实例化一个派生类对象,其基类ctor是私有的?
由于派生类ctor隐式调用基类ctor(私有),编译器会给出错误.
请考虑以下示例代码:
#include <iostream>
using namespace std;
class base
{
private:
base()
{
cout << "base: ctor()\n";
}
};
class derived: public base
{
public:
derived()
{
cout << "derived: ctor()\n";
}
};
int main()
{
derived d;
}
Run Code Online (Sandbox Code Playgroud)
此代码给出了编译错误:
access_private_ctor_in_base_class.cpp:在构造函数
derived::derived()': accessing_private_ctor_in_base_class.cpp:9: error:base :: base()'是私有的access_private_ctor_in_base_class.cpp:18:错误:在此上下文中
如何修改代码以删除编译错误?
HttpServlet是一个包含所有实现方法的抽象类.为什么它是抽象的?
我得到的最常见的答案是,限制实例化HttpServlet.但是还有其他方法可以做到这一点,就像私有构造函数会限制实例化一样.
我可以理解他们正在遵循模板方法设计模式.如果某些方法是抽象的,那么即使用户的业务逻辑不需要它们,用户也会最终实现所有这些方法.
但如果HttpServlet不是抽象的,用户仍然可以扩展它并覆盖require方法.
至少通过"抽象"这个词的字典含义,对我来说,拥有一个带有所有实现方法的抽象类并没有任何意义.
是的,抽象和具体方法的组合是可以的.
但是如果你正在创建一个类抽象,为什么不将这些方法抽象为子类必须覆盖的呢?或者可能根本没有宣布它是抽象的?
喜欢doGet()或是doPost()这种情况.
我们可以通过使其构造函数为private来限制类的对象的创建.但是仍然可以从类中调用此构造函数.有没有办法在Java中阻止这种情况?
谢谢.
java ×4
c++ ×3
constructor ×3
scala ×2
apply ×1
c# ×1
case-class ×1
enums ×1
inheritance ×1
macros ×1
servlets ×1
singleton ×1