Main:
public class Main { public static void main(String [] args) { Foo<String, Location> foo = new Foo<>(); foo.add("abc", new Location(5, 6)); } }
Location:
public class Location { public int x; public int y; public Location(int x, int y) { this.x = x; this.y = y; } @Override public String toString() { return "(" + x + "," + y + ")"; } }
Foo class:
public class Foo<K, T> { public void add(K name, T loc) { System.out.println(name + " " + loc.x + loc.y); } }
When I try to run the program I get the “question title” error, I don’t know what that happens, and how to fix that.
Advertisement
Answer
One way is to use instanceof
operator if you are expecting a type that you know. This is a demo.
public void add(K name, T loc) { if(loc instanceof Location) { System.out.println(name + " " + ((Location)loc).x + ((Location)loc).y); } }
UPDATE
As Stephen C mentioned that Foo
class potentially needs hard-coded knowledge of the capabilities of each of the possible types T
. Which is (in theory) every Java reference type! The correct way to solve this is to declare <T extends SomeInterface>
and provide getters in the interface to get the x
and y
attributes
So instead of knowing about all possible types of T
we can make T
extend SomeInterface
and get the information by calling the getters which can be implemented in the respective type
.
Make T
extend LocationInfo
interface to get info about x and y
class Foo<K, T extends LocationInfo> { public void add(K name, T loc) { System.out.println(name + " " + loc.getX() + loc.getY()); } } interface LocationInfo { int getX(); int getY(); }
And include the implementation in Location
class
class Location implements LocationInfo { public int x; public int y; public Location(int x, int y) { this.x = x; this.y = y; } @Override public String toString() { return "(" + x + "," + y + ")"; } public int getX() { return x; } public int getY() { return y; } }