Is there a way to refer to the current type with a type variable?

java generics
java generics self reference
java this type
java generic concrete type
java generics inheritance return type
java abstract class generic return type
java class cannot inherit from its type parameter
java generic return this

Suppose I'm trying to write a function to return an instance of the current type. Is there a way to make T refer to the exact subtype (so T should refer to B in class B)?

class A {
    <T extends A> foo();
}

class B extends A {
    @Override
    T foo();
}

To build on StriplingWarrior's answer, I think the following pattern would be necessary (this is a recipe for a hierarchical fluent builder API).

SOLUTION

First, a base abstract class (or interface) that lays out the contract for returning the runtime type of an instance extending the class:

/**
 * @param <SELF> The runtime type of the implementor.
 */
abstract class SelfTyped<SELF extends SelfTyped<SELF>> {

   /**
    * @return This instance.
    */
   abstract SELF self();
}

All intermediate extending classes must be abstract and maintain the recursive type parameter SELF:

public abstract class MyBaseClass<SELF extends MyBaseClass<SELF>>
extends SelfTyped<SELF> {

    MyBaseClass() { }

    public SELF baseMethod() {

        //logic

        return self();
    }
}

Further derived classes can follow in the same manner. But, none of these classes can be used directly as types of variables without resorting to rawtypes or wildcards (which defeats the purpose of the pattern). For example (if MyClass wasn't abstract):

//wrong: raw type warning
MyBaseClass mbc = new MyBaseClass().baseMethod();

//wrong: type argument is not within the bounds of SELF
MyBaseClass<MyBaseClass> mbc2 = new MyBaseClass<MyBaseClass>().baseMethod();

//wrong: no way to correctly declare the type, as its parameter is recursive!
MyBaseClass<MyBaseClass<MyBaseClass>> mbc3 =
        new MyBaseClass<MyBaseClass<MyBaseClass>>().baseMethod();

This is the reason I refer to these classes as "intermediate", and it's why they should all be marked abstract. In order to close the loop and make use of the pattern, "leaf" classes are necessary, which resolve the inherited type parameter SELF with its own type and implement self(). They should also be marked final to avoid breaking the contract:

public final class MyLeafClass extends MyBaseClass<MyLeafClass> {

    @Override
    MyLeafClass self() {
        return this;
    }

    public MyLeafClass leafMethod() {

        //logic

        return self(); //could also just return this
    }
}

Such classes make the pattern usable:

MyLeafClass mlc = new MyLeafClass().baseMethod().leafMethod();
AnotherLeafClass alc = new AnotherLeafClass().baseMethod().anotherLeafMethod();

The value here being that method calls can be chained up and down the class hierarchy while keeping the same specific return type.


DISCLAIMER

The above is an implementation of the curiously recurring template pattern in Java. This pattern is not inherently safe and should be reserved for the inner workings of one's internal API only. The reason is that there is no guarantee the type parameter SELF in the above examples will actually be resolved to the correct runtime type. For example:

public final class EvilLeafClass extends MyBaseClass<AnotherLeafClass> {

    @Override
    AnotherLeafClass self() {
        return getSomeOtherInstanceFromWhoKnowsWhere();
    }
}

This example exposes two holes in the pattern:

  1. EvilLeafClass can "lie" and substitute any other type extending MyBaseClass for SELF.
  2. Independent of that, there's no guarantee self() will actually return this, which may or may not be an issue, depending on the use of state in the base logic.

For these reasons, this pattern has great potential to be misused or abused. To prevent that, allow none of the classes involved to be publicly extended - notice my use of the package-private constructor in MyBaseClass, which replaces the implicit public constructor:

MyBaseClass() { }

If possible, keep self() package-private too, so it doesn't add noise and confusion to the public API. Unfortunately this is only possible if SelfTyped is an abstract class, since interface methods are implicitly public.

As zhong.j.yu points out in the comments, the bound on SELF might simply be removed, since it ultimately fails to ensure the "self type":

abstract class SelfTyped<SELF> {

   abstract SELF self();
}

Yu advises to rely only on the contract, and avoid any confusion or false sense of security that comes from the unintuitive recursive bound. Personally, I prefer to leave the bound since SELF extends SelfTyped<SELF> represents the closest possible expression of the self type in Java. But Yu's opinion definitely lines up with the precedent set by Comparable.


CONCLUSION

This is a worthy pattern that allows for fluent and expressive calls to your builder API. I've used it a handful of times in serious work, most notably to write a custom query builder framework, which allowed call sites like this:

List<Foo> foos = QueryBuilder.make(context, Foo.class)
    .where()
        .equals(DBPaths.from_Foo().to_FooParent().endAt_FooParentId(), parentId)
        .or()
            .lessThanOrEqual(DBPaths.from_Foo().endAt_StartDate(), now)
            .isNull(DBPaths.from_Foo().endAt_PublishedDate())
            .or()
                .greaterThan(DBPaths.from_Foo().endAt_EndDate(), now)
            .endOr()
            .or()
                .isNull(DBPaths.from_Foo().endAt_EndDate())
            .endOr()
        .endOr()
        .or()
            .lessThanOrEqual(DBPaths.from_Foo().endAt_EndDate(), now)
            .isNull(DBPaths.from_Foo().endAt_ExpiredDate())
        .endOr()
    .endWhere()
    .havingEvery()
        .equals(DBPaths.from_Foo().to_FooChild().endAt_FooChildId(), childId)
    .endHaving()
    .orderBy(DBPaths.from_Foo().endAt_ExpiredDate(), true)
    .limit(50)
    .offset(5)
    .getResults();

The key point being that QueryBuilder wasn't just a flat implementation, but the "leaf" extending from a complex hierarchy of builder classes. The same pattern was used for the helpers like Where, Having, Or, etc. all of which needed to share significant code.

However, you shouldn't lose sight of the fact that all this only amounts to syntactic sugar in the end. Some experienced programmers take a hard stance against the CRT pattern, or at least are skeptical of the its benefits weighed against the added complexity. Their concerns are legitimate.

Bottom-line, take a hard look at whether it's really necessary before implementing it - and if you do, don't make it publicly extendable.

Javanotes 8.1, Answers for Quiz on Chapter 5, Note that generally, there are lots of correct answers to a given question. When a variable is of object type (that is, declared with a class or interface as its A reference to the new object is returned as the value of the expression "new Kumquat()". same method in different ways, depending on the actual type of the object. At any moment, you can use the GetTypeCode method to determine the current run-time type, or the TypeOf Operator to find out if the current run-time type is compatible with a specified type. To determine the exact type an object variable currently refers to. On the object variable, call the GetType method to retrieve a System.Type object.

You should be able to do this using the recursive generic definition style that Java uses for enums:

class A<T extends A<T>> {
    T foo();
}
class B extends A<B> {
    @Override
    B foo();
}

PHP Programming with MySQL: The Web Technologies Series, A variable with a value of NULL has a value assigned to it—null is really the value “no value. 6+ The term N U L L refers to a data type 2. Working with Data Types Variables can contain many different kinds of values—for If someone asks you for your name, your age, or the current time, you don't usually stop to  No, that is not possible. The type of a variable has to be known at compile time. You can declare a variable of type object, it will be capable of storing any data type.

Just write:

class A {
    A foo() { ... }
}

class B extends A {
    @Override
    B foo() { ... }
}

assuming you're using Java 1.5+ (covariant return types).

Functional Programming Languages and Computer Architecture: 5th , In any case, the expression dynamic a is of type dyn, without any mention of of the type variables free in their type should be free in the current typing environment. Since polymorphic functions can be nested arbitrarily, this means that all  If you define a reference variable whose type is an interface, any object you assign to it must be an instance of a class that implements the interface. As an example, here is a method for finding the largest object in a pair of objects, for any objects that are instantiated from a class that implements Relatable :

If you want something akin to Scala's

trait T {
  def foo() : this.type
}

then no, this is not possible in Java. You should also note that there is not much you can return from a similarly typed function in Scala, apart from this.

How to: Determine What Type an Object Variable Refers To, The type of that data can change during run time. At any moment, you can use the GetTypeCode method to determine the current run-time type,  A variable definition specifies a data type, and contains a list of one or more variables of that type as follows − type variable_list; Here, type must be a valid C++ data type including char, w_char, int, float, double, bool or any user-defined object, etc., and variable_list may consist of one or more identifier names separated by commas.

I may not fully understood the question, but isn't it enough to just do this (notice casting to T):

   private static class BodyBuilder<T extends BodyBuilder> {

        private final int height;
        private final String skinColor;
        //default fields
        private float bodyFat = 15;
        private int weight = 60;

        public BodyBuilder(int height, String color) {
            this.height = height;
            this.skinColor = color;
        }

        public T setBodyFat(float bodyFat) {
            this.bodyFat = bodyFat;
            return (T) this;
        }

        public T setWeight(int weight) {
            this.weight = weight;
            return (T) this;
        }

        public Body build() {
            Body body = new Body();
            body.height = height;
            body.skinColor = skinColor;
            body.bodyFat = bodyFat;
            body.weight = weight;
            return body;
        }
    }

then subclasses won't have to use overriding or covariance of types to make mother class methods return reference to them...

    public class PersonBodyBuilder extends BodyBuilder<PersonBodyBuilder> {

        public PersonBodyBuilder(int height, String color) {
            super(height, color);
        }

    }

Type Class (System), For any type, there is only one instance of Type per application domain. GetType method to determine the runtime type of each object in an object array. Gets a value indicating whether the current Type encompasses or refers to another an instance of a specified type can be assigned to a variable of the current type. By Doug Lowe. A reference type is a data type that’s based on a class rather than on one of the primitive types that are built in to the Java language. The class can be a class that’s provided as part of the Java API class library or a class that you write yourself. Either way, when you create an object from a class, Java allocates the amount of memory the object requires to store the object.

Using an Interface as a Type (The Java™ Tutorials > Learning the , If you define a reference variable whose type is an interface, any object you is a method for finding the largest object in a pair of objects, for any objects that  When using variables of type Object, you may need to take different actions based on the class of the object; for example, some objects might not support a particular property or method. Visual Basic provides two means of determining which type of object is stored in an object variable: the TypeName function and the TypeOfIs operator.

Programming Microsoft Dynamics™ NAV 2015, The syntax is as follows: DateVariable := DWY2DATE ( DayValue [ CALCDATE allows us to calculate a date value assigned to a Date data type variable. The calculation is based on a Date Expression applied to a Base Date (Reference Date). DateExpression [, BaseDateValue]) There are a number of ways in which we  If there is an increase in market demand in a perfectly competitive market, then in the short run prices will a. there will be no change in the demand curves faced by individual firms in the market b. the demand curves for firms will shift downward c. the demand curves for firms will become more elastic d. will rise

Using the this Keyword (The Java™ Tutorials > Learning the Java , Within an instance method or a constructor, this is a reference to the current object The constructors provide a default value for any member variable whose initial which constructor to call, based on the number and the type of arguments​. PowerShell variables are loosely typed, which means that they aren't limited to a particular type of object. A single variable can even contain a collection, or array, of different types of objects at the same time. The data type of a variable is determined by the .NET types of the values of the variable.

Comments
  • I think the answer by @PaulBellora is excellent. To summarize it: there is a solution but it's fragile; it's better to use this solution when you write and control the whole tree of classes/subclasses. A careless programmer that extends the abstract class could produce a subclass that doesn't make sense or is outright wrong (see EvilLeafClass below).
  • Better to altogether avoid the confusion caused by recursive generic types and use the Self type via Manifold.
  • +1. This can be a good solution if you know that people extending MyClass will always follow the rules you've established. There is no way to enforce this using compilation rules, though.
  • @StriplingWarrior Agreed - it's fit more for the internal workings of one's API, not to be publicly extendable. I actually used this construct recently for a fluent builder pattern. For example one could call new MyFinalClass().foo().bar() where foo() is declared in a superclass and bar() is defined in MyFinalClass. Only the final concrete classes are exposed outside the package so my teammembers can't mess with self() etc. I hadn't realized until now that intermediate classes maintaining the type parameter couldn't be used directly though.
  • how do you mean? without the bound for SELF, everything still works fine.
  • By already providing a (final) implementation for self() in the SelfTyped class there is no need to have its trivial implementation in each sub class. @SuppressWarnings("unchecked") protected final SELF self() { return (SELF) this; } This way EvilLeafClass cannot return arbitrary objects. Instead, if it doesn't follow the contract, a ClassCastException will be thrown.
  • @PaulBellora One thing I've just noticed is that MyBaseClass<?> mbc2 = new MyBaseClass<>().baseMethod(); does work (compiles and runs successfully) without requiring MyBaseClass to be abstract. At least in my case, this is sufficient since the only advantage of the type is to be able to chain all the available methods properly.
  • Is A an abstract class in this case? Otherwise I can't see how it would implement foo().
  • what happens when class C extends B?
  • @Kublai: I expect it would be, but it's possible that it could use reflection to implement foo if the constructor for A takes a Class<T> as a parameter.
  • @jpalecek: That's a good point: C.foo would return a B. Java's enums get around this problem by preventing people from extending enum types. We obviously don't have that luxury in this case.
  • @Stripling - please see my answer. I tried to build on what you have but looking for confirmation.
  • I'm not sure that OP wants A's foo to return type A...just something that extends it. It looks like only in the specific case of B does he want foo to return a B.
  • @Michael: This may well suit the OP's needs. If he calls new A().foo();, he should have a strongly-typed A. If he calls new B().foo();, he should have a strongly-typed B. The only thing that's lacking is that the definition of A does not enforce that any B extending it must return a B from foo.