通用方法 ] 在 JAVA 中扩展多个类型参数
generic method ] extends multiple type parameter in JAVA
我正在制作一个获取对象和字符串的通用方法。
一开始是这样的..
public static <K, V> V getValue(Pair<K,V> _pair, String k){ ... }
我想也许它和主要的一样有效class
GrandChildPair<String, Integer> tst = new GrandChildPair<>("dd", 1);
Integer result = Util.getValue(tst,"dd");
但我想绑定类型扩展到 childPair 而不是 Grand one..
限制这个..访问?直到 ChildPair 行,而不是在 GrandChildPair 中唤醒它。
所以我首先尝试了方法定义,
public static <K extends ChildPair<K,V>, V extends ChildPair<K,V> V getValue (
但是是的,这很愚蠢,所以我在 java 中搜索了大约 3 个小时关于多类型参数扩展但我还没有找到..
我找到了其他单一类型的 pram extends examples 但我找不到 extend a whole
通用类型(可能不擅长搜索..)
有什么我可以做的吗?
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 根据 @OleV.V. 更新了对 类 不允许的检查评论
我认为您不能完全 强制该方法不接受 GrandChildPair 作为参数,因为 java 将其视为 ChildPair 和 Pair 的类型。我还认为,如果您必须这样做,那么这些关系可能必须 re-designed,因为这不是正确的方法。
有个不太好的路要走:
主要
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());
}
}
}
实用程序
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();
}
}
其他孩子对
public class OtherChildPair<K, V> extends ChildPair<K, V> {
public OtherChildPair(K k, V v) {
super(k, v);
}
}
输出
35
null
error: call not allowed
error: call not allowed
您只需要做几件事就可以让它发挥作用。这是正确的getValue()
:
public static <K,V> V getValue (ChildPair<K,V> _pair, K k) {
if (k != _pair.getK()) return null;
else return _pair.getV();
}
- 开头只需要指定
K
和V
两个类型参数:static <K,V>
.
- 输入参数可以是简单的
ChildPair<K,V>
所以它会接受ChildPair
和GrandChildPair
,但是会拒绝Pair
。
- 我相信您想确保
getValue()
、k
的第二个参数与 K
对的类型始终相同。因此,我将其指定为 K k
。您可以使用 extends
使其更加灵活:public static <K,V,K2 extends K> V getValue (ChildPair<K,V> _pair, K2 k)
.
因此这将按设计被拒绝:
Pair<String, Integer> pair = new Pair<>("someone", 35);
Integer age = Util.getValue(pair, "someone"); // compiler error
这会起作用:
ChildPair<String, Integer> childPair = new ChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);
这也是:
ChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);
还有这个:
GrandChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);
我正在制作一个获取对象和字符串的通用方法。
一开始是这样的..
public static <K, V> V getValue(Pair<K,V> _pair, String k){ ... }
我想也许它和主要的一样有效class
GrandChildPair<String, Integer> tst = new GrandChildPair<>("dd", 1);
Integer result = Util.getValue(tst,"dd");
但我想绑定类型扩展到 childPair 而不是 Grand one.. 限制这个..访问?直到 ChildPair 行,而不是在 GrandChildPair 中唤醒它。 所以我首先尝试了方法定义,
public static <K extends ChildPair<K,V>, V extends ChildPair<K,V> V getValue (
但是是的,这很愚蠢,所以我在 java 中搜索了大约 3 个小时关于多类型参数扩展但我还没有找到.. 我找到了其他单一类型的 pram extends examples 但我找不到 extend a whole 通用类型(可能不擅长搜索..)
有什么我可以做的吗?
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 根据 @OleV.V. 更新了对 类 不允许的检查评论
我认为您不能完全 强制该方法不接受 GrandChildPair 作为参数,因为 java 将其视为 ChildPair 和 Pair 的类型。我还认为,如果您必须这样做,那么这些关系可能必须 re-designed,因为这不是正确的方法。
有个不太好的路要走:
主要
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());
}
}
}
实用程序
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();
}
}
其他孩子对
public class OtherChildPair<K, V> extends ChildPair<K, V> {
public OtherChildPair(K k, V v) {
super(k, v);
}
}
输出
35
null
error: call not allowed
error: call not allowed
您只需要做几件事就可以让它发挥作用。这是正确的getValue()
:
public static <K,V> V getValue (ChildPair<K,V> _pair, K k) {
if (k != _pair.getK()) return null;
else return _pair.getV();
}
- 开头只需要指定
K
和V
两个类型参数:static <K,V>
. - 输入参数可以是简单的
ChildPair<K,V>
所以它会接受ChildPair
和GrandChildPair
,但是会拒绝Pair
。 - 我相信您想确保
getValue()
、k
的第二个参数与K
对的类型始终相同。因此,我将其指定为K k
。您可以使用extends
使其更加灵活:public static <K,V,K2 extends K> V getValue (ChildPair<K,V> _pair, K2 k)
.
因此这将按设计被拒绝:
Pair<String, Integer> pair = new Pair<>("someone", 35);
Integer age = Util.getValue(pair, "someone"); // compiler error
这会起作用:
ChildPair<String, Integer> childPair = new ChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);
这也是:
ChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);
还有这个:
GrandChildPair<String, Integer> grandChildPair = new GrandChildPair<>("gh", 20);
Integer childAge = Util.getValue(childPair, "sss");
System.out.println(childAge);