简体   繁体   中英

What is Java's 'self' keyword

I'm trying to write a factory method in an abstract class in Java (so I want it to return a new instance of the extending class, rather than the super-class).

In PHP I'd do this using the self keyword:

abstract class Superclass {
    public static function factory($arg) {
        return new self($arg);
    }

    private function __construct($arg) {}

    abstract public function doSomething() {}
}

Does Java have a keyword like self I can use for this?

No; in Java, static methods are not inherited in the same way as non-static methods are. A subclass will have the static methods of its superclass, but when they execute, they will execute in context of the superclass - so there is no keyword that can be used in static methods to find out what class the method was invoked through.

Edit: A more precise formulation is that static methods are not inherited at all; however, the language allows us to use Subclass.foo() to call the static method Superclass.foo() .

Based on what you seem to want to achieve, you might want to implement the Abstract Factory pattern . It goes approximately like this:

public abstract class Superclass {}
public class SubclassA extends Superclass {}
public class SubclassB extends Superclass {}

public abstract class AbstractFactory {
    public abstract Superclass Create();
}

public class FactoryA extends AbstractFactory {
    public Superclass Create() {
        return new SubclassA();
    }
}

public class FactoryB extends AbstractFactory {
    public Superclass Create() {
        return new SubclassB();
    }
}

Now, you can eg create a method that takes an AbstractFactory (which, in reality, will be either a FactoryA or a FactoryB ). Calling Create() on this object will produce either a SubclassA or a SubclassB .

Edit: Fixed compilation error (forgot to make the factories extend AbstractFactory ).

If you absolutely have to you can use this code form a static context:

Class cls = new Object() { }.getClass().getEnclosingClass();
Object instance = cls.newInstance();

Your class need to have a nullary constructor.

You need some hacks to achieve this. One way I can think of to obtain this is:

public static <T extends SuperClass> T factory(Class<T> clazz) {
    return clazz.newInstance();
}

I don't think it is possible in Java to find out the name of the "current" subclass. And especially some dynamic object generation won't be possible.

So you'll need to define that static function in every subclass instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM