Benjy Kessler
Benjy Kessler

Reputation: 7636

Instantiation of stateless objects in Java

Is there any way in Java to avoid instantiating a stateless object? There is no real difference between a static function and a stateless object for example:

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

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

Functionality wise these two alternatives do the same thing and in general every stateless class can be converted to a static function. There are two main differences though:

  1. Instantiating a static class takes both time and memory where neither are needed. You only really need to store the code you don't need to allocate an object on the heap and a pointer to a vtable.
  2. static functions are very limited in Java. They can not be used with Generics, the static compare can never be used by a class that must receive a compare.

Therefore a static function is better in theory because it provides all the functionality of a stateless class but without the runtime and memory overheads. A static function is much less powerful in Java because it can't be called through a Generic type. Is there any way to benefit from both worlds?

Edit

I want to write a generic class as follows:

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;
  }
}

I can't write this. I have to accept a Comparator in Array's constructor and create aComparator interface that CompareInts implements.

Upvotes: 3

Views: 1076

Answers (5)

Jason C
Jason C

Reputation: 40336

Use the stateless objects.

If the object is stateless you'd never really need to allocate more than one, in theory (e.g. allocate a single static instance and reuse it). It is unlikely that you would ever use a significant amount of memory for such objects.

Your concerns about memory usage and instantiation time are nothing to worry about. In your example you're speaking of a couple of bytes and a few microseconds added to an entire sort operation -- It's completely negligible.

The passing of a this pointer to a method will be negligible as well, and I imagine the optimizer would take care of it anyways.

So, set your concerns aside and stick with clear, maintainable, easy-to-implement code. If you are having performance problems, profile, and I guarantee you will not find that your bottleneck is here.

Upvotes: -1

Puce
Puce

Reputation: 38132

Maybe static method references is what you are looking for: http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

E.g.:

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

Upvotes: 0

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382170

You need an instance, just as you need a function in functional languages where functions are first class citizens.

But you don't need to create a new instance each time, you can store that instance in a static variable of your Comparator class.

Upvotes: 2

Rick Riemer
Rick Riemer

Reputation: 84

Having only a private zero-argument constructor prevents instantiation of a class.

E.g.:

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

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

It's good practice to then make the class final.

Upvotes: -1

sp00m
sp00m

Reputation: 48827

Generics can be used with static methods:

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

Upvotes: 2

Related Questions