Human
Human

Reputation: 10815

Java equivalent of Objective-C instancetype?

In Objective-C, instancetype can be used as the return type of methods that return an instance of the class they are called on (or a subclass of that class).

What is the equivalent of instancetype in Java?

Upvotes: 5

Views: 538

Answers (3)

Amin Negm-Awad
Amin Negm-Awad

Reputation: 16660

I'm no Javaist but likely there is no equivalent, because Java needs it only rarely. (And Objective-C do so, too.)

Please note that in Objective-C you do not need it most of the time, too. This is, because the compiler infers the "real" return type from the receiver, even it is declared id. This applies to -init…, +alloc…, -new…:

To determine whether a method has an inferred related result type, the first word in the camel-case selector (e.g., “init” in “initWithObjects”) is considered, and the method will have a related result type if its return type is compatible with the type of its class and if:

  • the first word is “alloc” or “new”, and the method is a class method, or
  • the first word is “autorelease”, “init”, “retain”, or “self”, and the method is an instance method.

In Java this is inferred for the new operator, too. The constructors does not have any return type, so it does not need to be inferred.

Up to here: No need for an (explicit) keyword in Java or Objective-C.

In some cases you have additional methods returning a new instance of the receivers class. Cloning/copying is such a case. In Java you have to type cast the result. In Objective-C you can use instancetype to make code easier to read. (BTW: NSObject's -copy has id as return type, not instancetype. But again usually this is no problem, because you typically assign the return value to a typed reference.)

So the short conclusion: In both Java and Objective-C the return type can be and is inferred by the compiler for most of the use cases. In rare use cases you have to explicitly cast in Java.

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533660

The closest to thing is to use generics

interface Base<B extends Base<B>> {
    // do something and return this.
    B append(String s);
}

interface SubBase<B extends SubBase<B>> extends Base<SubBase<B>> {
    // append returns a SubBase<B>
}

class MyClass implements SubBase<MyClass> {
    public MyClass append(String s) {
         // do something
         return this;
    }
}

It's not so elegant, but it works.

Upvotes: 4

If you mean something like this:

class Vehicle {
    instancetype doNothing() {return this;}
}
class Car extends Vehicle {}

Car c = new Car().doNothing(); // no compile errors here

There is no equivalent.

One workaround that's sometimes used is to pass the type as a generic parameter:

class Vehicle<instancetype> {
    instancetype doNothing() {return this;}
}
class Car extends Vehicle<Car> {}

Car c = new Car().doNothing(); // works

but then you can't use the type Vehicle without getting warnings everywhere (it has to be Vehicle<?>).

Upvotes: 0

Related Questions