java缺省包详解_Java在其它包中无法引用缺省包中的类

1、现象

1.1 问题场景

最近,在写测试代码时,将一个类(这里暂且称为ClassA)放在在缺省包中,也就是说,直接放在了src目录下,没有创建包。然后,将这个类打入了jar文件,提供给另外的工程(这里称为ProjA)用,结果发现了非常神奇的现象。

在ProjA中,如果从缺省包中引用ClassA,可以引用到。但是,如果创建一个包,在包中引用ClassA就会发现,引用不到,报错类找不到。第一反应是,是不是需要import啊?想写一个import语句。但是,由于ClassA放在缺省包中,也没法通过import包的方式引用这个类(因为没有包名)。这就比较尴尬了。

搜了下,发现不只是jar包中存在这个问题。这是java的一个普遍现象:Java在其它包中无法引用缺省包中的类。

1.2 机制解析

其实,细想一下,这个也比较好理解。因为如果在包中不指定报名引用一个类,一般是引用同一个包中的类。直觉上,我们可能会认为,如果在同一个包中找不到的这个类,java应该取缺省包看看,找下缺省包中是否能够找到这个类。然而,令人失望的是java现在没有这个机制(当然,也有可能是因为引入这个机制之后,会导致混乱。嗯,这个原因的可能性非常大。。。)。

2、解决方法

这里解决的方法也算是比较容易。大家在写java代码时,一定要注意尽量将类放在一个显式指定的包中,不要直接扔在缺省包中。

上面的方法适用于事前控制。如果情况已经出了,那么该如何在其他包中访问缺省包中的类呢?答案就是在于java的反射机制。

2.1 反射介绍

在Java语言中,可以通过如下的反射机制调用一个类的方法。具体如下:

首先通过反射获得指定类对应的Class对象

Class c = Class.forName("被调用类名");

获得指定类中的方法(通过传入方法名、参数类型等确认)

Method method= c.getMethod("被调用方法名", new Class[] { 参数列表类型 });

通过invoke方法,传入执行方法的类实例和方法参数,完成方法调用

Object value = method.invoke(class.newInstance(), new Object[]{ new String("参数一"),new String("参数二")});

如果要调用的方法是类的静态方法,就不需要传入实例,实例指定为null即可。

Object value = method.invoke(null, new Object[]{ new String("参数一"),new String("参数二")});

比如,想调用的类名为MyClass,其中有方法为String myMethod(String str1,String str2);则调用如下:

Class class = Class.forName("MyClass");

Method method= snmpHandler.getMethod("myMethod", new Class[] { String.class,String.class });

String value = method.invoke(class.newInstance(), new Object[]{ new String("str1"), new String("str2")});

//如果是静态方法

//String value = method.invoke(null, new Object[]{ new String("str1"), new String("str2")});

2.2 例子

先上代码:

HelloWorld.java:

/**

* Created by chengxia on 2019/4/13.

*/

public class HelloWorld {

public static void helloWorld(String name, String words){

System.out.println("Below is the output of HelloWorld class in the Default package.");

System.out.println(name + " said: " + words);

}

}

代码的工程结构如下图。

b7f70bd2dfc4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Test Module Structure

(1) CallHelloWorld1.java

package com.util.call;

/**

* Created by chengxia on 2019/4/13.

*/

public class CallHelloWorld1 {

public static void main(String []args){

HelloWorld.helloWorld("Kobe", "Mamba out!");

}

}

CallHelloWorld1类在包com.util.call中,当其引用HelloWorld类时,报错找不到,如下图。

b7f70bd2dfc4?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

Cannot Find Class in Default Package

这里为了下面的测试能够正常运行,在下面将报错的这行注释掉了。

(2) CallHelloWorld0.java

/**

* Created by chengxia on 2019/4/13.

*/

public class CallHelloWorld0 {

public static void main(String []args){

HelloWorld.helloWorld("Kobe", "Mamba out!");

}

}

CallHelloWorld0由于也在缺省包,所以可以正常引用HelloWorld类。运行如下:

Below is the output of HelloWorld class in the Default package.

Kobe said: Mamba out!

Process finished with exit code 0

(3) CallHelloWorld2.java

package com.util.call;

import java.lang.reflect.Method;

/**

* Created by chengxia on 2019/4/13.

*/

public class CallHelloWorld2 {

public static void main(String []args){

try

{

Class c = Class.forName("HelloWorld");

Method m = c.getMethod("helloWorld", new Class[]{String.class, String.class});

m.invoke(null, new Object[]{new String("Kobe"), new String("Mamba out!")});

}catch(Exception e){

e.printStackTrace();

}

}

}

CallHelloWorld2类在包com.util.call中,为了能正常调用HelloWorld类的方法,用了反射。可以正常运行,如下。

Below is the output of HelloWorld class in the Default package.

Kobe said: Mamba out!

Process finished with exit code 0

参考资料

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值