Im making a generic method which get an object and string.
it works at first like this..
public static <K, V> V getValue(Pair<K,V> _pair, String k){ ... }
I thought maybe it works as in main class
GrandChildPair<String, Integer> tst = new GrandChildPair<>("dd", 1);
Integer result = Util.getValue(tst,"dd");
But I wanna bound type extends to childPair not Grand one.. To limit this ..access? till ChildPair lines and not woking that in GrandChildPair. so I've tried first in method definition,
public static <K extends ChildPair<K,V>, V extends ChildPair<K,V> V getValue (
but yes It was dumb so I've searched for maybe 3 hours about multiple type parameter extends in java but I couldn't found yet.. I found other single type pram extends examples but I could't find extend a whole generic type (maybe not good at searching..)
Is there any I can do?
public class Util {
///define method
//// //Type parameters //return type// method name ( prams...) {
public static (Pair extends ChildPair) V getValue (Pair<K,V> _pair, String k) {
if (k != _pair.getK()) return null;
else return _pair.getV();
}
}
public class Pair<K, V> {
private K k;
private V v;
Pair(K k, V v) {
this.k = k;
this.v = v;
}
public K getK() {
return k;
}
public V getV() {
return v;
}
}
public class ChildPair<K, V> extends Pair<K, V> {
public ChildPair(K k, V v) {
super(k, v);
}
}
public class GrandChildPair<K, V> extends ChildPair<K, V> {
public GrandChildPair(K k, V v) {
super(k, v);
}
}
public class Main {
public static void main(String[] args) {
Pair<String, Integer> pair = new Pair<>("someone", 35);
Integer age = Util.getValue(pair, "someone");
System.out.println(age);
ChildPair<String, Integer> childPair = new ChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);
}
}
EDIT updated the check on what classes are not allowed based on @OleV.V.'s comment
I don't think you can cleanly force the method to not accept GrandChildPair as a parameter because java considers it as type of ChildPair and also Pair. I also think that if you have to do this then maybe these relationships have to be re-designed, because this is not the right way to go.
There is a not very good way to go:
Main
public class Main {
public static void main(String[] args) {
try {
// works
Pair<String, Integer> pair = new Pair<>("someone", 35);
Integer age = (Integer) Util.getValue(pair, "someone");
System.out.println(age);
} catch (Exception e) {
System.out.println("error: " + e.getMessage());
}
try {
// mismatch in K so returns null
ChildPair<String, Integer> childPair = new ChildPair<>("ch", 20);
Integer childAge = (Integer) Util.getValue(childPair, "sss");
System.out.println(childAge);
} catch (Exception e) {
System.out.println("error: " + e.getMessage());
}
try {
// error
GrandChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 40);
Integer grandChildAge = (Integer) Util.getValue(grandChildPair, "gh");
System.out.println(grandChildAge);
} catch (Exception e) {
System.out.println("error: " + e.getMessage());
}
try {
// error
OtherChildPair<String, Integer> otherChildPair = new OtherChildPair<>("oh", 60);
Integer otherChildAge = (Integer) Util.getValue(otherChildPair, "oh");
System.out.println(otherChildAge);
} catch (Exception e) {
System.out.println("error: " + e.getMessage());
}
}
}
Util
public class Util {
public static Object getValue(Pair<?, ?> _pair, String k) throws Exception {
// check specific class and return / throw error
// if (_pair instanceof GrandChildPair) {
// OR check if it extends ChildPair and return / throw error
if (_pair.getClass().isAssignableFrom(ChildPair.class) == false) {
throw new Exception("call not allowed");
}
if (_pair.getK().equals(k) == false) {
return null;
}
return _pair.getV();
}
}
OtherChildPair
public class OtherChildPair<K, V> extends ChildPair<K, V> {
public OtherChildPair(K k, V v) {
super(k, v);
}
}
Output
35
null
error: call not allowed
error: call not allowed