美文网首页IT@程序员猿媛MacOS, Java和IDEAJava 杂谈
Java在其它包中无法引用缺省包中的类

Java在其它包中无法引用缺省包中的类

作者: SpaceCat | 来源:发表于2019-04-13 23:26 被阅读40次

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语言中,可以通过如下的反射机制调用一个类的方法。具体如下:

  1. 首先通过反射获得指定类对应的Class对象
    Class c = Class.forName("被调用类名");
  2. 获得指定类中的方法(通过传入方法名、参数类型等确认)
    Method method= c.getMethod("被调用方法名", new Class[] { 参数列表类型 });
  3. 通过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);
    }
}

代码的工程结构如下图。


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类时,报错找不到,如下图。


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

参考资料

相关文章

  • Java在其它包中无法引用缺省包中的类

    1、现象 1.1 问题场景 最近,在写测试代码时,将一个类(这里暂且称为ClassA)放在在缺省包中,也就是说,直...

  • Java进阶系列之对象克隆

    大家都知道在Java中所有的类都是缺省的继承自Java语言包中的Object类的,查看它的源码,你可以把你的JDK...

  • jupyter相关使用

    1、当无法引用自己的包时——  从网上扒下来的整个学习项目的包,但是在学习过程中,发现不能引用其它包里面已经写好的...

  • JNI基础(7): JNI访问和修改Java类

    7.1 java中的基本类型和引用类型的签名规则 jni中 java类的签名为: L + 包名 + 类名,再将原来...

  • AutoMapper的简单使用

    李芬妹妹抓紧联系我在引用nuget包中添加AutoMapper包,在Using中进行引用! 先准备2个类 :Clo...

  • Java集合类—— List

    什么是集合? 集合类存放于java.util包中。集合类存放的都是对象的引用,而非对象本身,我们称集合中的对象就是...

  • Java常用类库-Date类

    Date 类 在 java.util 包中,因此在使用 Date 类时需要导入该包。Date 类 表示特定的时间瞬...

  • Java容器笔记(二):不同集合实现类的特点与区别

    package java.util包中的Collection相关接口和类如下图: 仅讨论Java.util包中的常...

  • Java--包

    JDK中主要包 Java中的常用包:java.lang说明:包含一些Java语言的核心类,如String,Math...

  • Java集合框架(一)

    集合类存放于java.util包中,集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象...

网友评论

    本文标题:Java在其它包中无法引用缺省包中的类

    本文链接:https://www.haomeiwen.com/subject/vaudwqtx.html