Java中无状态对象的实例化

时间:2014-08-13 09:07:07

标签: java static

Java中是否有任何方法可以避免实例化无状态对象?静态函数和无状态对象之间没有真正的区别,例如:

class CompareInts {
  Integer compare(Integer a, Integer b) {
    return a.compareTo(b);
  }

static Integer compare(Integer a, Integer b) {
  return a.compareTo(b);
}

功能明智这两个替代方案做同样的事情,通常每个无状态类都可以转换为静态函数。但是有两个主要的区别:

  1. 实例化静态类需要时间和内存,而不需要时间和内存。您只需要存储不需要在堆上分配对象的代码和指向vtable的指针。
  2. 静态函数在Java中非常有限。它们不能与泛型一起使用,静态比较永远不能被必须接收比较的类使用。
  3. 因此,静态函数在理论上更好,因为它提供了无状态类的所有功能,但没有运行时和内存开销。静态函数在Java中的功能要小得多,因为它不能通过Generic类型调用。有没有办法从这两个世界中受益?

    修改

    我想编写一个泛型类,如下所示:

    class Array<Type, Comparator> {
      Type[] elements;
      // array stuff
    
      Type getMax() {
        Type maxElement = Type.getSmallestLegalValue();
        for (Type element : elements) {
          maxElement = Comparator.compare(maxElement, element) > 0 ? maxElement : element;
        }
        return maxElement;
      }
    }
    

    我写不出来。我必须在Comparator的构造函数中接受Array,并创建Comparator实现的CompareInts接口。

5 个答案:

答案 0 :(得分:2)

泛型可以与静态方法一起使用:

static <T extends Number & Comparable<T>> int compare(T a, T b) {
    return a.compareTo(b);
}

答案 1 :(得分:2)

您需要一个实例,就像您需要函数语言中的函数一样,函数是一等公民。

但是每次都不需要创建新实例,可以将该实例存储在Comparator类的静态变量中。

答案 2 :(得分:0)

使用无状态对象。

如果对象是无状态的,理论上你永远不需要分配多个对象(例如,分配一个静态实例并重用它)。您不可能为这些对象使用大量内存。

您对内存使用和实例化时间的担忧无需担心。在您的示例中,您说的是几个字节,并且在整个排序操作中添加了几微秒 - 这完全可以忽略不计。

this指针传递给方法也是可以忽略不计的,我想无论如何优化器都会处理它。

因此,将您的顾虑放在一边,坚持使用清晰,可维护,易于实现的代码。如果您遇到性能问题,我会保证您不会发现您的瓶颈在这里。

答案 3 :(得分:0)

只有一个私有零参数构造函数会阻止实例化类。

E.g:

public final class Sample {
    public static int method() {
        return 1;
    }

    private Sample() {
        // private to avoid instantiation
    }
}

然后让课程最终成为好习惯。

答案 4 :(得分:0)

也许您正在寻找静态方法引用:http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

E.g:

return elements.stream().max(SomeComparator::someStaticCompareMethod);