同包同名的类的时候,使用哪个,哪个优先

最近项目中,遇到了一个问题,起因是这个样子的:

项目A,它是一个web项目(使用spring开发,tomcat下部署,提供jsp页面,供用户使用),会引入产品包,暂且用product.jar来代替产口包吧吧。web项目最后会打成war包来部署。

项目B,它呢,不需要页面,换言之,它也是web项目(使用spring开发,tomcat下部署),只是单纯的引入spring的定时任务来处理业务数据。说到底,它也是一个web项目,只不过不需要html,jsp这些东东,类似于windows里的服务吧,不需要有GUI窗口。它最终也是打成war包来发布。但是,和项目A的不同之处在于它需要把项目A,先打成JAR包,然后放在项目B中引用。这么想像或许可以更为直接:项目A中,定义了好多实体类,然后在项目B中引入项目A的JAR包,这么说理,便顺理成章了。

说到这里,介绍了两个项目之间的关系。那么,问题也就随之而来了:

产品包product.jar中,有个Order类,它继承了抽像类AbstractOrder类。如下所示:

public class Order extends AbstractOrder{
}
order里什么属性也没有,产品的设计思想是,每个项目都会有自己的业务,在这里写自己的代码(比如属性)。而AbstractOrder里,则是产品里的自己的代码。
我们在Order里添加自己的属性,然后发布项目A时,什么问题都没有。


现在发布项目B,先把项目A打成jar包,把项目B打成WAR包(WAR包里的LIB目录会含有项目A的JAR文件)。启动项目时却报错了,大致是找不到Order里的属性。。。

到目前为止,项目B里,存在了两个Order类,一个是产品包里的,一个是项目A打成的JAR包里的。两个Order,到底用的哪个呢,系统又是怎么控制的呢?所以引入话题:

同包同名的类,会先加载哪个呢???


同样的问题,我们在开发中经常会引入第三方的JAR,很有可能会出现同名字的类(这里是指同包,同类),那么VM是怎么样决定使用哪个的呢?


先在Eclpise中做个例子。



Order里的代码如下所示:

package org.test;

public class Order {
	public void say() {
		System.out.println("这是JAR文件里的");
	}
}


TestMain里的代码如下所示:

package org.test;

public class TestMain {
	public static void main(String[] args) {
		Order order = new Order();
		order.say();
	}
}

运行TestMain,打印如下所示:

上面的输出再正常不过了。接下来,模拟下把这个项目打成JAR文件。然后下一步,再放到当前这个项目里进行引用。另外,改下代Order里的代码。


Order里现在的代码为

package org.test;

public class Order {
	public void say() {
		System.out.println("这是项目里的");
	}
}

说下刚才的动作。Order里的代码(“这是JAR文件里的”)已经被打成JAR包(文件名为ac.jar)了,并且在项目中引用了。然后又把项目里的Order的代码,输出换成了"这是项目里的"。到目前为目,两个Order对象了吧(同包同类名),那么到底用哪个呢?再运行一下,看看什么结果

这是项目里的

结果显示,用的是项目里的。第一个问题:为什么是用的项目里的呢?第二个问题:能不能告诉eclpise用JAR文件里的呢?

先来回答第二个问题,是可以的。可以告诉eclipse用JAR里的。具体做法如下

如题所示,只要让ac.jar,处理列表中的第一条即可。选中ac.jar,点击右侧的top即可。然后再运行一下,就会发现用的是JAR文件里的了。


再来回答第一个问题:为什么会这样呢?

长话短说,这个类加载器用关。即classloader。


再抛出一个问题,这是在eclipse中可以指定顺序,如果是在tomcat里运行,lib目录下一大堆的JAR包,怎么指定顺序啊?

再来做个实验,在CMD里,进入项目目录,手动使用java命令来执行这个class文件。

E:\workspace\test-using-which-one-jar>java -cp ./bin;./src/ac.jar org.test.TestM
ain
这是项目里的
先加载项目里的,后加载jar文件。

E:\workspace\test-using-which-one-jar>java -cp ./src/ac.jar;./bin org.test.TestM
ain
这是JAR文件里的

先加载JAR文件里的,后加载项目。


-cp参数用于指定classpath目录。到这里可以看出,为什么eclipse里可以指定顺序了吧。



如果是在tomcat里运行,lib目录下一大堆的JAR包,怎么指定顺序啊?

通过实验得出,根JAR文件的文件名有关。按照字母的顺序加载JAR文件。有了这个类以后,后面的类则不会加载了。具体的可以自己做实验。
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值