【问题标题】:Java Generics class and constructorJava 泛型类和构造函数
【发布时间】:2018-05-07 06:14:27
【问题描述】:

我想创建父类来执行 GetInstance。但我总是崩溃。 mInstance = new Instance<>(); 总是崩溃这一行

public class Instance<T> {

    public Instance<T> mInstance;

    public Instance<T> GetInstance() {
        return mInstance;
    }

    public <T> Instance() {
        mInstance = new Instance<>();
    }
}


public class Timer extends Instance<Timer> {

}

java.lang.StackOverflowError 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.familyfit.google.pushups.global.Instance.(Instance.java:21) 在 com.fami

【问题讨论】:

  • 错误是什么?
  • 提出错误.....
  • 你想让 Instance 成为单例吗?
  • 是的......
  • 你不应该在构造函数中调用你的构造函数。如果需要单例,请改用静态方法

标签: java android generics constructor


【解决方案1】:

你做错了

在您的构造函数中,您递归调用自身,因此是 stackoverflow。

要么将mInstance 的初始化移动到类外部,要么使其成为静态。

试试这个:

public static class Instance<T> {

    private static final Instance<?> mInstance = new Instance<>();

    @SuppressWarnings("unchecked")
    public Instance<T> GetInstance() {
        // Make generic static instance. 
        // Strategy used similar to Collections.emptyList() implementation
        return (Instance<T>) mInstance;
    }

    private Instance() {

    }
}

【讨论】:

  • 致投反对票的人:如果您想投反对票,请发表评论。不要仅仅因为你不懂java就投反对票。
  • 我也有同感。
  • 糟糕的一天哈哈
【解决方案2】:

这就是 IntelliJ 使用他的向导编写 Singleton 的方式。

public final class Singleton{

private static final Singleton ourInstance = new Singleton();

public static Singleton getInstance() {
    return ourInstance;
}

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

这样,一个单例只会被创建一次。请注意私有构造函数,它不允许您创建更多实例,而 static final 实例只有一个此类对象。至少,public static Singleton getInstance 方法会返回实例。请记住,在某些情况下,您会将单例类的其他方法声明为 synchronized,但这取决于您的类的业务逻辑。

编辑:正如另一位用户建议的那样,最好将类标记为 final 以防止对单例逻辑进行不必要的修改。

【讨论】:

  • 建议同时创建类final,以防止通过子类创建实例
【解决方案3】:

您有 2 个小错误,导致您的单例类无法正常工作。首先,您的mInstance 不是该类的静态字段,这意味着Instance 类的每个实例(错误地选择了名称TBH,使用更具体的名称)将拥有自己的mInstance,从而破坏了整体的目的,一个实例。

其次,您有一个泛型类,遗憾的是它在单例环境中效果不佳。因为当你总是只有一个实例时,引入泛型是没有意义的。因为那样你就可以用String 或者你正在使用的类型硬编码泛型变量T

要克服这些问题,您需要按以下方式更改您的课程:

public final class Instance {

     private static Instance mInstance;

     public static Instance getInstance(){
         if(mInstance == null){
             mInstance = new Instance();
         }
         return mInstance;
     }

     private Instance(){
         // your initialization logic
     }
}

我也做了一些正常的决定,例如创建类final,以不让第二个实例弹出,例如通过子类化。然后我还创建了构造函数和mInstnace 字段private。为了再次防止对类本身进行不必要的更改,并且不允许用户创建多个实例。

【讨论】:

  • mInstance == null 将在多个线程尝试访问此静态函数时引发条件
  • @MạnhQuyếtNguyễn 你完全正确,但这只有在你有多个线程时才有意义,引入一层同步可能是一个甚至可能不会使用的开销
猜你喜欢
  • 1970-01-01
  • 2013-10-13
  • 1970-01-01
  • 2011-12-28
  • 2010-10-16
  • 2019-02-20
  • 1970-01-01
  • 2020-09-11
  • 1970-01-01
相关资源
最近更新 更多