当x的类型为A,且A直接实现了Comparable接口(比较类型必须为A类本身)时,返回x的运行时类型;否则返回null。
class A implements Comparable<A>{}, A x = new A();
static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) {
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class) // bypass checks
return c;
if ((ts = c.getGenericInterfaces()) != null) {
for (int i = 0; i < ts.length; ++i) {
if (((t = ts[i]) instanceof ParameterizedType) &&
((p = (ParameterizedType)t).getRawType() ==
Comparable.class) &&
(as = p.getActualTypeArguments()) != null &&
as.length == 1 && as[0] == c) // type arg is c
return c;
}
}
}
return null;
}
举例分析:结果来看只有当传入对象的运行时类型符合”class C implements Comparable<C>”这个条件时,返回对象的运行时类型,否则返回null
public class Demo {
public static void main (String[]args) {
System.out.println(comparableClassFor(new A())); // null ,A does not implement Comparable.
System.out.println(comparableClassFor(new B())); // null ,B implements Comparable, compare to Object.
System.out.println(comparableClassFor(new C())); // class com.sankuai.payrc.demo.Demo$C, C implements Comparable, compare to itself.
System.out.println(comparableClassFor(new D())); // null ,D implements Comparable, compare to its sub type.
System.out.println(comparableClassFor(new F())); // null ,F is C's sub type.
}
static class A {
}
static class B implements Comparable<Object> {
@Override
public int compareTo(Object o) {
return 0;
}
}
static class C implements Comparable<C> {
@Override
public int compareTo(C o) {
return 0;
}
}
static class D implements Comparable<E> {
@Override
public int compareTo(E o) {
return 0;
}
}
static class E {
}
static class F extends C {
}
static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) {
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class) // bypass checks
return c;
if ((ts = c.getGenericInterfaces()) != null) {
for (int i = 0; i < ts.length; ++i) {
if (((t = ts[i]) instanceof ParameterizedType) &&
((p = (ParameterizedType)t).getRawType() ==
Comparable.class) &&
(as = p.getActualTypeArguments()) != null &&
as.length == 1 && as[0] == c) // type arg is c
return c;
}
}
}
return null;
}
}
过程详解
x instanceof Comparable
c = x.getClass()
getClass()返回的只会是它的运行时类型,可以简单的理解为它的实际类型,也就是new它的时候的类型。 有一种例外情况:匿名对象。当匿名对象调用getClass()时返回的是依赖它的对象的运行时类型,并以1,2,3…的索引区分。
public class Demo {
public static void main(String[] args) {
D d = new D();
System.out.println(new A(){}.getClass()); // class com.sankuai.payrc.demo.Demo$1
System.out.println(new B(){}.getClass()); // class com.sankuai.payrc.demo.Demo$2
System.out.println(new Comparable<Object>(){
@Override
public int compareTo(Object o) {
return 0;
}}.
getClass());//class com.sankuai.payrc.demo.Demo$3
System.out.println(d.c.getClass()); //class com.sankuai.payrc.demo.D$1
System.out.println(d.getClass()); // class com.sankuai.payrc.demo.D
}
}
abstract class A{}
abstract class B{}
abstract class C{}
class D{
C c;
D(){
c= new C(){};
}
}
ts = c.getGenericInterfaces()
返回的是该对象的运行时类型“直接实现”的接口,这意味着:
public class Demo {
public static void main(String[] args) {
Grand child = new Child();
System.out.println(child.getClass());
Type[] types = child.getClass().getGenericInterfaces();
if (types != null) {
for (Type type : types) {
System.out.println(type.getTypeName());//java.lang.Cloneable
}
}
}
}
abstract class Grand implements Comparable<Grand>{}
abstract class Super extends Grand implements Serializable {}
class Child extends Super implements Cloneable {public int compareTo(Grand o)
{return 0;
}
}
这两个方法虽然没有出现在comparableClassFor(Object x)中,这里也顺便看一下。通过简单的例子,可以看到:
getSuperclass()返回的是直接父类的类型,不包括泛型参数。
getGenericSuperclass()返回的是包括泛型参数在内的直接父类。
注意如果父类声明了泛型,但子类继承时没有为父类实现该泛型,这时候也是没有泛型参数的。
public class Demo {
public static void main(String[] args) {
Grand child = new Child();
System.out.println(child.getClass());//class com.sankuai.payrc.demo.Child
Type type1 = child.getClass().getGenericSuperclass();
Class<?> class1 = child.getClass().getSuperclass();
//com.sankuai.payrc.demo.Super<java.lang.Integer, java.lang.Integer>
System.out.println(type1.getTypeName());
//com.sankuai.payrc.demo.Super
System.out.println(class1.getTypeName()); // Super
Grand child2 = new Child2();
Type type2 = child2.getClass().getGenericSuperclass();
Class<?> class2 = child2.getClass().getSuperclass();
//com.sankuai.payrc.demo.Super<A, B>
System.out.println(type2.getTypeName());
//com.sankuai.payrc.demo.Super
System.out.println(class2.getTypeName());
}
}
abstract class Grand implements Comparable<Grand>{}
abstract class Super<T,E> extends Grand implements Serializable{}
class Child extends Super<Integer,Integer> implements Cloneable {public int compareTo(Grand o) {return 0;}}
class Child2<A,B,C> extends Super<A,B>{public int compareTo(Grand o) {return 0;}}
((t = ts[i]) instanceof ParameterizedType)
ParameterizedType是Type接口的子接口,表示参数化的类型,即实现了泛型参数的类型。需要注意:
如果直接用bean对象instanceof ParameterizedType,结果都是false。
Class对象不能instanceof ParameterizedType,编译会报错。
只有用Type对象instanceof ParameterizedType才能得到想要的比较结果。可以这么理解:一个Bean类不会是ParameterizedType,只有代表这个Bean类的类型(Type)才可能是ParameterizedType。
实现泛型参数,可以是给泛型传入了一个真实的类型,或者传入另一个新声明的泛型参数;只声明泛型而不实现,instanceof ParameterizedType为false。
public class Demo {
public static void main(String[] args) {
Grand child1 = new Child();
Grand child2_1 = new Child2();
Grand child2_2 = new Child2<String, String>();
Child2<String, String> child2_3 = new Child2<String, String>();
Child3<String, String> child3 = new Child3<String,String>();
System.out.println(child1 instanceof ParameterizedType); // flase
System.out.println(child2_1 instanceof ParameterizedType); // flase
System.out.println(child2_2 instanceof ParameterizedType); // flase
System.out.println(child2_3 instanceof ParameterizedType); // flase
System.out.println(child1.getClass().getGenericSuperclass().getTypeName());
//com.sankuai.payrc.demo.Super<java.lang.String, java.lang.String>
System.out.println(child2_1.getClass().getGenericSuperclass().getTypeName());
//com.sankuai.payrc.demo.Super<A, B>
System.out.println(child3.getClass().getGenericSuperclass().getTypeName());
//com.sankuai.payrc.demo.Super
System.out.println(child1.getClass().getGenericSuperclass() instanceof ParameterizedType); // true
System.out.println(child2_1.getClass().getGenericSuperclass() instanceof ParameterizedType); // true
System.out.println(child3.getClass().getGenericSuperclass() instanceof ParameterizedType); // flase
// System.out.println(child1.getClass() instanceof ParameterizedType); // Complie Errors
}
}
class Grand{}
class Super<A,B> extends Grand{}
class Child extends Super<String,String>{}
class Child2<A,B> extends Super<A,B>{}
class Child3<A,B> extends Super{}
public class Demo {
public static void main(String[] args) {
Grand grand = new Grand();
Type[] types = grand.getClass().getGenericInterfaces();
if (types != null) {
for (Type type : types) {
System.out.println(type.getTypeName() + " " + (type instanceof ParameterizedType));
// com.sankuai.payrc.demo.IA<java.lang.String, java.lang.Integer> true
// com.sankuai.payrc.demo.IB false
// com.sankuai.payrc.demo.IC<X> true
// com.sankuai.payrc.demo.ID false
}
}
}
}
interface IG<X,Y>{}
interface IA<X,Y>{}
interface IB extends IG{}
interface IC<X>{}
interface ID<X>{}
class Grand<X> implements IA<String,Integer>,IB,IC<X>,ID{}
(p = (ParameterizedType)t).getRawType()
public class Demo {
public static void main(String[] args) {
Grand grand = new Grand();
Type[] types = grand.getClass().getGenericInterfaces();
if (types != null) {
for (Type type : types) {
if(type instanceof ParameterizedType){
System.out.println(((ParameterizedType) type).getRawType());
// interface com.sankuai.payrc.demo.IA
// interface com.sankuai.payrc.demo.IC
}
}
}
}
}
interface IG<X,Y>{}
interface IA<X,Y>{}
interface IB extends IG{}
interface IC<X>{}
interface ID<X>{}
class Grand<X> implements IA<String,Integer>,IB,IC<X>,ID{}
(as = p.getActualTypeArguments())
与getRawType()相对应,getActualTypeArguments()以数组的形式返回泛型参数列表。
注意,这里返回的是实现该泛型时传入的参数,可以看下方代码的打印结果:
当传入的是真实类型时,打印的是全类名。
当传入的是另一个新声明的泛型参数时 ,打印的是代表该泛型参数的符号。
public class Demo {
public static void main(String[] args) {
Grand grand = new Grand();
Type[] types = grand.getClass().getGenericInterfaces();
if (types != null) {
for (Type type : types) {
if(type instanceof ParameterizedType){
System.out.println(type.getTypeName());
Type[] typeArguments = ((ParameterizedType) type).getActualTypeArguments();
if(typeArguments != null){
for (Type typeArg : typeArguments) {
System.out.println(typeArg.getTypeName());
// Output result:
// IA<java.lang.String, java.lang.Integer>
// java.lang.String
// java.lang.Integer
// IC<X>
// X
}
}
}
}
}
}
}
interface IG<X,Y>{}
interface IA<X,Y>{}
interface IB extends IG{}
interface IC<X>{}
interface ID<X>{}
class Grand<X> implements IA<String,Integer>,IB,IC<X>,ID{}
ParameterizedType接口还有一个getOwnerType()方法,如果该类型是一个内部类/接口,返回它的外部类/接口。如果该类型不是内部类/接口,返回null。
public class Demo {
public static void main(String[] args) {
Outer<String> outer = new Outer<>();
Outer<String>.Child<Integer> child = outer.new Child<>();
Type type = child.getClass().getGenericSuperclass();
if(type instanceof ParameterizedType){
System.out.println(((ParameterizedType) type).getOwnerType()); //Outer<X>
}
}
}
class Outer<X>{
class Inner<Y>{}
class Child<Y> extends Inner<Y>{}
}
static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) { // 判断是否实现了Comparable接口
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class)
return c; // 如果是String类型,直接返回String.class
if ((ts = c.getGenericInterfaces()) != null) { // 判断是否有直接实现的接口
for (int i = 0; i < ts.length; ++i) { // 遍历直接实现的接口
if (((t = ts[i]) instanceof ParameterizedType) && // 该接口实现了泛型
((p = (ParameterizedType)t).getRawType() == // 获取接口不带参数部分的类型对象
Comparable.class) && // 该类型是Comparable
(as = p.getActualTypeArguments()) != null && // 获取泛型参数数组
as.length == 1 && as[0] == c) // 只有一个泛型参数,且该实现类型是该类型本身
return c; // 返回该类型
}
}
}
return null;
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/mingyuli/article/details/120438945
内容来源于网络,如有侵权,请联系作者删除!