关于静态编译引发的问题NoSuchException

7 篇文章 0 订阅

发生的环境 jdk7 tomcat7

问题描述。

1.改了一个实体类A中某一个成员变量的类型,以及受影响的引用的修改。

2.但是其中一个B类引用了实体类A,但是情况特殊,并没有受到影响报错,就没有修改该类。

3.因为迟迟不能上线,现在要对B类进行修改,修改过后,将B类的class文件单独打包上服务器。启动正常,调用修改过A类变量的时候报错。

4.也就是说实体类A在服务器上还是旧的,但是有一个引用过A的B类修改后上线出现的问题

5.最后解决是将A类退回线上版本 重新编译 重新传B.class

解决很简单,但是当时也是有点懵。

错误信息如下。

错误信息很明显,就是在调用model.setHh(D)V,没有找到这类方法,参数是double,返回值是void的方法。

如下代码 demo

package com.wpao.test.modeltype;
public class Model {
	private int hh;

	public int getHh() {
		return hh;
	}

	public void setHh(int hh) {
		this.hh = hh;
	}

}
//这个是修改之前的实体文件是int类型
package com.wpao.test.modeltype;
public class Model {
	private double hh;

	public double getHh() {
		return hh	;
	}

	public void setHh(double hh) {
		this.hh = hh;
	}
}
//这个是修改之后的实体类型 类型为double

 

​
package com.wpao.test.modeltype;

public class Abc {
	//这个是调用类的方法 
	public static void main(String[] args) {
			try {
				Model m = new Model();
				//实体改成double和int类型是不影响这句话编译的,不会报错
				m.setHh(1);
				System.out.println(m.getHh());
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	}
}

​

现在运行以上代码 就会报出上述异常。

当时出现的情况获取Molde的方式是

Model model = (Model)list.get(i);

model.getXxx();

然后报错,当时也是脑子秀逗了,认为和泛型擦除有关系。所以去调查了下泛型擦除,找到一篇文档如下。

 

 

当您编写对泛型方法的调用时,编译器会插入一个casts在返回类型的时候,并将其擦除。

编译器自动插入强制转换 Employee

也就是说,编译器将方法调用转换为两个虚拟机指令

raw:这是一种规定了generic type参数,但是引用的时候却没有指明的一种引用。

1.调用了泛型方法Pair.getFirst

2.将return回来的Object强转为Employee

 

下面是网上摘抄的

  Java的泛型是伪泛型。在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(type erasure)。

       Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。

    如在代码中定义的List<object>和List<String>等类型,在编译后都会编程List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。

顺便回忆了一下泛型,貌似和这个地方出现的问题没有啥关系,应该是思路错了。

然后只能看下字节码,对比下A类和类的区别

右边的是原始的Model类 左边是新的Abc类,引用也是新的Model类

在Abc.class中setHh和gethh在静态编译后已经是为double 但是在旧的Model.class中hh变量还是int型

所以在运行调用时导致了NoSuchException

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值