Home > Net >  Java: Can instanceof also check "enclosing classes"?
Java: Can instanceof also check "enclosing classes"?

Time:08-27

Is instanceof able to check also the enclosing class (not sure if that is the right wording for my problem)?

Please see below.

Car.java

public class Car
{
    public static class Wheel {}
}

class CarA extends Car {}

class CarB extends Car {}

x.java

public class x
{
    public static void main (String [] args)
    {
        System.out.println ("*******");
        
        CarA.Wheel caw = new CarA.Wheel ();
        CarB.Wheel cbw = new CarB.Wheel ();
        System.out.println (caw instanceof CarA.Wheel);
        System.out.println (caw instanceof CarB.Wheel);
        System.out.println (cbw instanceof CarA.Wheel);
        System.out.println (cbw instanceof CarB.Wheel);
    }
}

** Output is **

true
true
true
true

But I am looking for

true
false
false 
true

I understand Wheel is always the same because of the extend but is there a way I can include CarA/CarB into the check (without implementiering Wheel in CarA and also in CarB)??

CodePudding user response:

No, with instanceof it is not possible. As you mentioned, the Wheel class is exists only once. Just because you access it through a different path doesn't make it a different class.

CodePudding user response:

You have exactly one Wheel class. Car.Wheel, CarA.Wheel and CarB.Wheel are just different names for that same class, and that is why instanceof evaluates to true for all of those types.

An alternative way of doing this without (explicitly) introducing a new field in Wheel or having every Car have their own Wheel class is to make Wheel non-static. Now the wheel knows which car it came from.

public class Car
{
    public class Wheel {
        public Car getCar() {
            return Car.this;
        }
    }
}
Car.Wheel wheel = new CarA().new Wheel();
System.out.println(wheel.getCar() instanceof CarA); // true
System.out.println(wheel.getCar() instanceof CarB); // false

Under the hood though, by making it non-static, a synthetic field is implicitly added to Wheel to record which car it came from, so you might consider this "cheating".

CodePudding user response:

I am not sure, functionally speaking, whether you need to have distinct wheels for each type of Car, or rather you need to know to which type of Car a specific wheel belongs to.

In the first case the answer is quick: you need to duplicate your class into WheelA and WheelB.

In the second case, you simply shouldn't use instanceof to check. You may do something like this:

public class Car
{
    public static class Wheel<T extends Car> {

        private final Class<T> carType;

        public Wheel(Class<T> carType) {
            this.carType = carType;
        }

        public Class<T> getCarType() {
            return carType;
        }
    }
}

Hence your code would change like this:

public class x
{
    public static void main (String [] args)
    {
        System.out.println ("*******");
        
        CarA.Wheel<CarA> caw = new CarA.Wheel<> (CarA.class);
        System.out.println (caw.getCarType().equals(CarA.class));
        System.out.println (caw.getCarType().equals(CarB.class));
    }
}
  • Related