java instance的问题

ningbohezhijun 2014-06-09 03:21:46
不经意间看到的代码,为了说明问题,仿写了一个

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

class MSGC_OPTION {
}

public class GenericDAO<T> {
private Class<T> entityClass;
protected GenericDAO() {
Type superClass = getClass().getGenericSuperclass();
if (superClass instanceof Class<?>) { // sanity check, should never happen
throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
}
Type trueType = ((ParameterizedType)superClass).getActualTypeArguments()[0];
this.entityClass = (Class<T>)trueType;
}

public static void main(String[] args) throws Exception {
OptionManager manager = new OptionManager();
//GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>();
}
}
class OptionManager extends GenericDAO<MSGC_OPTION> {
}



我的问题就是
if (superClass instanceof Class<?>) { // sanity check, should never happen
throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
}
这个if为什么为false呢?
Class<?>通配符不是应该可以匹配所有Class吗,这里不是很清楚,求指教,谢谢!
...全文
312 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
sinat_23915723 2014-11-25
  • 打赏
  • 举报
回复
yangweihong20110929 说的很白了,这是 class的代码: public Type getGenericSuperclass() { if (getGenericSignature() != null) { // Historical irregularity: // Generic signature marks interfaces with superclass = Object // but this API returns null for interfaces if (isInterface()) return null; return getGenericInfo().getSuperclass(); } else return getSuperclass(); } 如果具有泛型签名,返回的是ParameterizedType接口,父接口是Type接口,但不是Class对象。这个时候instanceof Class<?>是为false的。 如果没有泛型签名,返回的是Class对象,Class对象也实现了Type接口。这个时候instanceof Class<?>是为true的。 ..... 我没想明白的就是获取类型参数为什么要通过getGenericSuperclass();来过渡一下?
草原的雨夜 2014-06-11
  • 打赏
  • 举报
回复
昨天有点忙,没回复楼主,今天有点时间,就帮楼主彻底解决这个疑问,
OptionManager manager = new OptionManager();
manager 这个对象如果加泛型,则
Type superClass = getClass().getGenericSuperclass();
这句代码获取的是ParameterizedType这个接口的实现实例,而这个接口不是class的子类,所以if里是false,可以获取trueType--即泛型,也就是实际的代码中的参数。但是如果不加泛型,则if里会是true,这时候会抛出异常,因为这时候的superClass就是GenericDAO的对象,也就是加了泛型后的ParameterizedType这个接口的rawType这个属性。上次没看明白楼主的意思,这样子解释楼主应该可以理解了吧。
草原的雨夜 2014-06-11
  • 打赏
  • 举报
回复
简单说,就是所有类都是Object的子类,但不是class的子类;在简单点可以这么理解,class类是用来反射的,除此之外,class类用的不是太多,如果一个对象是getClass()这种方式或类名.class的方式获取的,则是class子对象,否则,就不是,getClass().getGenericSuperclass();获取的是一个ParameterizedTypeImpl类型的对象,不是class。 楼主慢慢理解吧,class只是一个反射时表示类的工具类,一定要区分Object和class类的区别。
ningbohezhijun 2014-06-11
  • 打赏
  • 举报
回复
引用 15 楼 yangweihong20110929 的回复:
昨天有点忙,没回复楼主,今天有点时间,就帮楼主彻底解决这个疑问,
OptionManager manager = new OptionManager();
manager 这个对象如果加泛型,则
Type superClass = getClass().getGenericSuperclass();
这句代码获取的是ParameterizedType这个接口的实现实例,而这个接口不是class的子类,所以if里是false,可以获取trueType--即泛型,也就是实际的代码中的参数。但是如果不加泛型,则if里会是true,这时候会抛出异常,因为这时候的superClass就是GenericDAO的对象,也就是加了泛型后的ParameterizedType这个接口的rawType这个属性。上次没看明白楼主的意思,这样子解释楼主应该可以理解了吧。
居然没看懂 我发现我对于Class这一块算不上懂。
致知Fighting 2014-06-10
  • 打赏
  • 举报
回复
引用 13 楼 ningbohezhijun 的回复:
[quote=引用 12 楼 ygycomon 的回复:] 看错了代码。 原因很简单,因为 Type superClass不是Class的子类,所以更加不可能是Class的instance
你的说法和我的一直以来的理解有偏差我认为,所有的类都只是Class的对象,没有Class的子类或类这一说。所以我不是很明白你所谓的“Type superClass不是Class的子类”是什么意思[/quote]
引用 13 楼 ningbohezhijun 的回复:
[quote=引用 12 楼 ygycomon 的回复:] 看错了代码。 原因很简单,因为 Type superClass不是Class的子类,所以更加不可能是Class的instance
你的说法和我的一直以来的理解有偏差我认为,所有的类都只是Class的对象,没有Class的子类或类这一说。所以我不是很明白你所谓的“Type superClass不是Class的子类”是什么意思[/quote] 你理论学歪了,所有类都是Object的子类,Class是用来描述类信息的
ningbohezhijun 2014-06-10
  • 打赏
  • 举报
回复
引用 12 楼 ygycomon 的回复:
看错了代码。 原因很简单,因为 Type superClass不是Class的子类,所以更加不可能是Class的instance
你的说法和我的一直以来的理解有偏差我认为,所有的类都只是Class的对象,没有Class的子类或类这一说。所以我不是很明白你所谓的“Type superClass不是Class的子类”是什么意思
致知Fighting 2014-06-10
  • 打赏
  • 举报
回复
看错了代码。 原因很简单,因为 Type superClass不是Class的子类,所以更加不可能是Class的instance
azhe1011 2014-06-10
  • 打赏
  • 举报
回复
为什么我回复不了
ningbohezhijun 2014-06-10
  • 打赏
  • 举报
回复
引用 9 楼 ygycomon 的回复:
	
protected Tmp() {
		Type superClass = getClass().getGenericSuperclass();
		if (superClass instanceof Class<?>) { // sanity check, should never happen
			throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
		}
	}
	public static void main(String[] args) {
		Tmp t = new Tmp<Object>();
	}
jdk1.6实测,if里返回的是true Exception in thread "main" java.lang.IllegalArgumentException: Internal error: TypeReference constructed without actual type information
兄台, OptionManager manager = new OptionManager(); 调试的结果是if为false 不是吗? 我想知道原因。
致知Fighting 2014-06-10
  • 打赏
  • 举报
回复
	
protected Tmp() {
		Type superClass = getClass().getGenericSuperclass();
		if (superClass instanceof Class<?>) { // sanity check, should never happen
			throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");
		}
	}
	public static void main(String[] args) {
		Tmp t = new Tmp<Object>();
	}
jdk1.6实测,if里返回的是true Exception in thread "main" java.lang.IllegalArgumentException: Internal error: TypeReference constructed without actual type information
ningbohezhijun 2014-06-10
  • 打赏
  • 举报
回复
哎,等了一天,居然不来了。。。
ningbohezhijun 2014-06-09
  • 打赏
  • 举报
回复
引用 6 楼 yangweihong20110929 的回复:
[quote=引用 5 楼 ningbohezhijun 的回复:] [quote=引用 4 楼 yangweihong20110929 的回复:] 这个不会反,在仔细调试下。 简单的说:instanceof关键字比较的是类在运行时是否是它本身或是它的子类的对象,当然这个对象可以包括泛型。 如果一个类的对象是A,没有泛型,而要比较的是B,也没有泛型,并且B是从A继承的,那么返回就是true,如果B有泛型,A没有,则肯定返回false,OptionManager manager = new OptionManager();这句肯定正确,在调试下试试,因为Type superClass = getClass().getGenericSuperclass();获取的对象superClass 是GenericDAO<MSGC_OPTION>,符合class<?>这种形式,并且class和GenericDAO这两个对象一样,而且泛型一样,但是GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>();肯定false,原因是superClass 是Object,没有泛型,所以即使Object和class一样,但是没有泛型,所以肯定false。如果你将class<?>的泛型去掉,那肯定就是你上面说的情况,如果还没明白可以继续问,正好今天没什么事,可以多回答点给你。
我真心的调试了啊 我们先解决哪个是true,哪个是false吧。 OptionManager manager = new OptionManager(); 得到的Type superClass = getClass().getGenericSuperclass();是GenericDAO<MSGC_OPTION> 而//GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>(); 得到的Type superClass = getClass().getGenericSuperclass();是Object 这个是和你说的一致的,这部分我能够理解,就是直接的父类类型。 [/quote] 额,抱歉,我要下班了,回家看看,明天在看看,也许是我哪里没看清楚。。[/quote] 已经非常感谢你了,这么有耐心的帮我。
草原的雨夜 2014-06-09
  • 打赏
  • 举报
回复
引用 5 楼 ningbohezhijun 的回复:
[quote=引用 4 楼 yangweihong20110929 的回复:] 这个不会反,在仔细调试下。 简单的说:instanceof关键字比较的是类在运行时是否是它本身或是它的子类的对象,当然这个对象可以包括泛型。 如果一个类的对象是A,没有泛型,而要比较的是B,也没有泛型,并且B是从A继承的,那么返回就是true,如果B有泛型,A没有,则肯定返回false,OptionManager manager = new OptionManager();这句肯定正确,在调试下试试,因为Type superClass = getClass().getGenericSuperclass();获取的对象superClass 是GenericDAO<MSGC_OPTION>,符合class<?>这种形式,并且class和GenericDAO这两个对象一样,而且泛型一样,但是GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>();肯定false,原因是superClass 是Object,没有泛型,所以即使Object和class一样,但是没有泛型,所以肯定false。如果你将class<?>的泛型去掉,那肯定就是你上面说的情况,如果还没明白可以继续问,正好今天没什么事,可以多回答点给你。
我真心的调试了啊 我们先解决哪个是true,哪个是false吧。 OptionManager manager = new OptionManager(); 得到的Type superClass = getClass().getGenericSuperclass();是GenericDAO<MSGC_OPTION> 而//GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>(); 得到的Type superClass = getClass().getGenericSuperclass();是Object 这个是和你说的一致的,这部分我能够理解,就是直接的父类类型。 [/quote] 额,抱歉,我要下班了,回家看看,明天在看看,也许是我哪里没看清楚。。
ningbohezhijun 2014-06-09
  • 打赏
  • 举报
回复
引用 4 楼 yangweihong20110929 的回复:
这个不会反,在仔细调试下。 简单的说:instanceof关键字比较的是类在运行时是否是它本身或是它的子类的对象,当然这个对象可以包括泛型。 如果一个类的对象是A,没有泛型,而要比较的是B,也没有泛型,并且B是从A继承的,那么返回就是true,如果B有泛型,A没有,则肯定返回false,OptionManager manager = new OptionManager();这句肯定正确,在调试下试试,因为Type superClass = getClass().getGenericSuperclass();获取的对象superClass 是GenericDAO<MSGC_OPTION>,符合class<?>这种形式,并且class和GenericDAO这两个对象一样,而且泛型一样,但是GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>();肯定false,原因是superClass 是Object,没有泛型,所以即使Object和class一样,但是没有泛型,所以肯定false。如果你将class<?>的泛型去掉,那肯定就是你上面说的情况,如果还没明白可以继续问,正好今天没什么事,可以多回答点给你。
我真心的调试了啊 我们先解决哪个是true,哪个是false吧。 OptionManager manager = new OptionManager(); 得到的Type superClass = getClass().getGenericSuperclass();是GenericDAO<MSGC_OPTION> 而//GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>(); 得到的Type superClass = getClass().getGenericSuperclass();是Object 这个是和你说的一致的,这部分我能够理解,就是直接的父类类型。
草原的雨夜 2014-06-09
  • 打赏
  • 举报
回复
这个不会反,在仔细调试下。 简单的说:instanceof关键字比较的是类在运行时是否是它本身或是它的子类的对象,当然这个对象可以包括泛型。 如果一个类的对象是A,没有泛型,而要比较的是B,也没有泛型,并且B是从A继承的,那么返回就是true,如果B有泛型,A没有,则肯定返回false,OptionManager manager = new OptionManager();这句肯定正确,在调试下试试,因为Type superClass = getClass().getGenericSuperclass();获取的对象superClass 是GenericDAO<MSGC_OPTION>,符合class<?>这种形式,并且class和GenericDAO这两个对象一样,而且泛型一样,但是GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>();肯定false,原因是superClass 是Object,没有泛型,所以即使Object和class一样,但是没有泛型,所以肯定false。如果你将class<?>的泛型去掉,那肯定就是你上面说的情况,如果还没明白可以继续问,正好今天没什么事,可以多回答点给你。
ningbohezhijun 2014-06-09
  • 打赏
  • 举报
回复
引用 1 楼 yangweihong20110929 的回复:
这个问题其实比较简单,因为没注释的那句代码的父类是有泛型的,所以?号是可以通配的,而注释的那句代码父类是Object,所以没有泛型,当然就if那就false了。
怎么感觉你说反了,虽然我不是很懂原理,但是代码我还是调试了的。 OptionManager manager = new OptionManager(); 调试的结果是if为false //GenericDAO<MSGC_OPTION> genericDAO = new GenericDAO<MSGC_OPTION>(); 调试的结果是if为true 能再讲清楚点吗?比如我想知道Class<?>,什么才是instance of Class<?>? 谢谢!
草原的雨夜 2014-06-09
  • 打赏
  • 举报
回复
换句话说,因为你superClass 为Object,所以没有泛型,当然就false,如果还不明白在问。
草原的雨夜 2014-06-09
  • 打赏
  • 举报
回复
这个问题其实比较简单,因为没注释的那句代码的父类是有泛型的,所以?号是可以通配的,而注释的那句代码父类是Object,所以没有泛型,当然就if那就false了。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧