0

Emmm,This problem is hard to describe. My code is like:

//this class use as parent public abstract class Test { //there is generic function public <T extend Test> function(List<T> param){ } } 

If a class is derived from 'Test' and I call function(List) on it, then the param type can be any of Test's children and is not fixed to be the child's class I'm calling the method on, which actually is what I want to achieve.

A feasible solution is:

 public <T extend Test> function(Class<T> clazz,List<T> param){ //check 'this' and clazz,if 'this' class not equal clszz,throw Exception if (this.getClass().equals(clazz)){ throw new Exception(); } } 

But is there a better solution? I think this problem can be solved during compilation instead of runtime. Sorry, my english is not good, But I want to know how to solve it.thanks

4
  • Mmmh, I don't think I got the issue. Could you try to rephrase? Commented Feb 6, 2021 at 17:39
  • I created a class use as parent ,the class hava a generic function ,look like : ``` public class Test { /** there is generic function,'List' just a example, * (maybe is a Any class has generic.To simplify the * problem, use list as an example.) * A class extending 'Test',and call this function, * param can be 'Test' list , or any 'Test' child * list. This is not i want, I expect param only be * the corresponding child list */ public <T extend Test> function(List<T> param){ } } ``` Commented Feb 7, 2021 at 2:41
  • Assume that both types inherit Test ``` public class Test1 extend Test{ } ``` ``` public class Test2 extend Test{ } ``` try call Test1 obj function : java //params List<Test> testList; List<Test1> test1List; List<Test2> test2List; Test1 test = new Test1(); / ** * it's okay for params is testList * it's okay for params is test2List * I expect param can only be test1List * / test1.function(test1List); Commented Feb 7, 2021 at 2:42
  • I think it is achievable,because child have specific type,and the function not static, so has 'this'. I thought of pseudo code : java public <T extend this.class> function(List<T> param){ } Commented Feb 7, 2021 at 2:42

2 Answers 2

2

One solution is to make Test itself generic, and require subclasses to declare themselves as the type parameter.

abstract class Test<T extends Test<T>> { public void function(List<T> list) { // ... } } class ChildA extends Test<ChildA> { // ... } class ChildB extends Test<ChildB> { // ... } 

Note that this isn't bulletproof since it's possible to declare e.g. class ChildB extends Test<ChildA> instead of extends Test<ChildB>, in which case function will have the wrong signature in ChildB. But as long as implementing classes follow the rules and provide themselves as the type parameter, then you get what you want.

Sign up to request clarification or add additional context in comments.

Comments

-1

Well, I understand your problem. At this level your can only fix the typings in each individual extending class. So you'll have a

public class Test1 extends Test { public <T extend Test1> function(List<T> param){ } } 

and a

public class Test2 extends Test { public <T extend Test2> function(List<T> param){ } } 

an so on.

You can't determine that some not-yet-known subclass will only accept its own type as a parameter, sorry.

If you really want to do that, generics don't have that functionality build-in and the snipplet you posted could be an option to do - but you just shouldn't need to depend on that.

You could optimize it a bit, because polymorphy gives you the specific class on this.getClass() and the other classname is Test.class.getSimpleName(). So following should do it:

this.getClass().equals(Test.class.getSimpleName()) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.