Suppose I have a class hierarchy as follow:
class Vehicle;
class Car extends Vehicle;
class Plane extends Vehicle;
I have a function which compares the two object
public <T extends Vehicle> generateDiff(T original, T copy)
At compile time, the method above guarantees the two objects is Vehicle
, but it cannot make sure the types of the two object are the same.
generateDiff(new Car(), new Car()); //OK
generateDiff(new Plane(), new Plane()); //OK
generateDiff(new Car(), new Plane()); //WRONG
Can I achive this at compile time using Generics?
P.s: currently, I've implemented it will throw exception if the Class
of two objects are not the same. But I'm not satisfied with this.
Thanks in advance.
Generics also provide type safety (ensuring that an operation is being performed on the right type of data before executing that operation). Hierarchical classifications are allowed by Inheritance. Superclass is a class that is inherited. The subclass is a class that does inherit.
To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound, which in this example is Number . Note that, in this context, extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).
Yes, you can (kind of)!
The type T
is being inferred from the arguments, but you can specify the type:
MyClass.<Car>generateDiff(new Car(), new Plane()); // generates a compile error
Without the typing the method, the type T
is inferred to be the narrowest class that satisfies the bounds as used, so for parameters Car
and Plane
, the narrowest type that will work is Vehicle
, so these two lines are equivalent:
generateDiff(new Car(), new Plane()); // type is inferred as Vehicle
MyClass.<Vehicle>generateDiff(new Car(), new Plane());
The above code assumes the generateDiff()
is a static method. If it's an instance method, you could type your class and have that type used in your method.
Once you get that deep into it, it gets a bit abstract. You would have to provide the class type for the function as well (see below). If you want to enforce such behavior, I would recommend writing separate methods that accept the types you wish to compare. Anyway:
public <C extends Vehicle> void generateDiff(Class<C> type, C original, C copy);
And you can use it as such:
generateDiff(Plane.class, new Plane(), new Plane()); // OK
generateDiff(Car.class, new Car(), new Car()); // OK
generateDiff(Plane.class, new Plane(), new Car()); // ERROR
generateDiff(Vehicle.class, new Plane(), new Car()); // OK
Not sure why any sane person would want to do this though! :)
It is not possible in my opinion, any method which can accept Vehicle as an argument will be able to accept CAR and PLANE. Since compiler dont know what kind of Objects will come(can be CAR, BUS, PLANE), it cannot guarentee that two params are of exactly same type. If some one extends CAR and creates a FORD? both objects are type CAR.
Only way to ensure this is at runtime using custom logic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With