导入其他包,轻松实现跨包调用 | 带你学《Java面向对象编程》之六十八

简介: 本节为读者介绍了不同的包之间如何调用其内的类-使用import导入其他包内容。

上一篇:一文带你迅速搞懂包是什么 | 带你学《Java面向对象编程》之六十七
【本节目标】
通过阅读本节内容,你将了解到如何使用import导入其他包实现跨包调用类、如何处理多个包中存在同名类的情况、静态导入纯静态类可以实现方法的直接调用等内容。

包的导入

利用包的定义实际上就可以将不同功能的类保存在不同的包之中,但是这些类彼此之间也一定会存在有互相调用的关系,那么在这种情况下就需要使用import语句来导入其它包中的程序类。
范例:定义一个程序类“cn.mldn.util.Message”,这个类负责进行一个消息数据的获取

package cn.mldn.util ;
public class Message {
    public String getContent() {
        return "www.mldn.cn" ;
    }
}

范例:定义一个测试类使用Message类“cn.mldn.test.TestMessage”。

package cn.mldn.test ;
import cn.mldn.util.Message ;      //导入其它包的类
public class TestMessage {
    public static void main(String  args[]) {
       Message msg = new Message() ;    //实例化类对象
         System.out.println(msg.getContent()) ;     //www.mldn.cn
    }
}

此时按照使用顺序来讲肯定是要先编译Message.java,而后再编译TestMessage.java,但是请思考一个问题:如果有一个程序代码,里面有100个类,彼此之间互相引用严格,此时怎么区分呢?那么这个时候最好的做法不是区分顺序,而是直接交给Java自己去完成:javac -d . *.java;
特别需要注意的是:关于public class 与class定义的区别?

  • public class:类名称必须与文件名称保持一致,一个*.java文件里面只允许有一个public class,同时如果一个类需要被其它的包所使用,那么这个类一定要定义为public class;
  • class:类名称可以与文件名称不一致,并且在一个.java文件里面可以提供有多个class定义,编译后将形成不同的.class文件,但是这些类只能被本包所访问,外包无法访问。
  • 在实际的开发之中往往在一个*.java源代码文件里面只会提供有一个程序,而这个程序类一般都使用public class定义;

程序类中定义的包名称必须采用小写字母的形式定义,例如:cn.mldn.util;
但是这个时候会有一个新的问题产生,有些时候可能会使用某一个包中的很多类,于是这样分开进行类的导入会比较麻烦,为了解决这样的问题,也可以使用通配符“*”来进行处理。

package cn.mldn.test ;
import cn.mldn.util.* ;     
public class TestMessage {
      public static void main(String  args[]) {
            Message msg = new Message() ;    //实例化类对象
            System.out.println(msg.getContent()) ;     //www.mldn.cn
      }
}

即便此时使用了“包.”的导入形式,那么也不表示要进行全部的加载,它会根据自己的需要加载所需要的程序类,而不需要的程序类是不会被加载的,所以是使用“”还是使用具体的类其最终性能是完全相同的。

但是如果在开发中采用的是“包.*”的形式进行包的导入时,那么会有一点比较麻烦:有可能两个不同的包中存在有相同的类名称。例如,现在假设TestMessage类由于某种需要要导入两个包:cn.mldn.util、org.demo,但是这两个包里面都有Message类。
cn.mldn.util.Message:

package cn.mldn.util ;
public class Message {
    public String getContent() {
        return "www.mldn.cn" ;
      }
}

org.demo.Message:

package org.demo;
public  class Message {
      public  String getInfo() {
            return "人民万岁!";
      }
}

由于某种需要在TestMessage类里面导入了两个包:

package cn.mldn.test ;
import cn.mldn.util.* ;       //导入其它包的类
import org.demo.* ;        //导入其它包的类
public class TestMessage {
      public static void main(String  args[]) {
            Message msg = new Message() ;    //实例化类对象
            System.out.println(msg.getContent()) ;     //www.mldn.cn
      }
}

程序编译:
javac-d . TestMessage.java

     org.demo中的类org.demo.Message和cn.mldn.util中的类cn.mld n.util.Message都匹配Test Message.java:6:错误:对Message的引用不明确

Message msg=new Message() ; //实例化类对象

org.demo中的类org.demo.Message和cn.mld n.util中的类cn.mld n.util.Message都匹配2个错误

这个时候就会发现类名称相同的时候就会出现不明确的引用处理,所以此时最简单的处理形式就是直接写上类的完整名称。

cn.mldn.util.Message msg = new cn.mldn.util.Message() ;

在日后的开发过程之中经常会见到大量的重名的类(包不重名),此时为了更好的解决问题,往往会使用类的完整名称进行操作。

包的静态导入

假如说现在有一个类,这个类中的全部方法都是static方法,那么按照原始做法肯定要导入程序所在的“包.类”,然后才可以通过类名称调用这些静态方法;
范例:定义一个MyMath数学类

package cn.mldn.util ;
public class MyMath {
   public static int add(int ... args) {
       int sum = 0 ;
       for (int temp : args) {
          sum += temp ;
       }
       return sum ;
   }
   public static int sub(int x , int y) {
             return x - y ;
   }
}

如果此时按照原始的方式进行导入处理,那么此时就需要导入包.类,而后通过类名称调用方法。
范例:原始方式使用

package cn.mldn.test ;
import cn.mldn.util.MyMath ;      
public class TestMath {
   public static void main(String  args[]) {
       System.out.println(MyMath.add(10 , 20 ,30)) ;
       System.out.println(MyMath.sub(30 ,20)) ;
   }   //执行结果:60    10
}

从JDK1.5开始,对于类中全部由静态方法提供的特殊类是可以采用静态导入处理形式的。
范例:静态导入处理

package cn.mldn.test ;
import static cn.mldn.util.MyMath.* ;      
public class TestMath {
    public static void main(String  args[]) {
       System.out.println(add(10 , 20 ,30)) ;
       System.out.println(sub(30 ,20)) ;
    }   //执行结果:60    10
}

当使用了静态导入处理之后就好比该方法是直接定义在主类中的,可以由主方法直接调用。

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:“化繁为简”-神奇的Jar命令 | 带你学《Java面向对象编程》之六十九
更多Java面向对象编程文章查看此处

相关文章
|
4月前
|
安全 Java API
JAVA并发编程JUC包之CAS原理
在JDK 1.5之后,Java API引入了`java.util.concurrent`包(简称JUC包),提供了多种并发工具类,如原子类`AtomicXX`、线程池`Executors`、信号量`Semaphore`、阻塞队列等。这些工具类简化了并发编程的复杂度。原子类`Atomic`尤其重要,它提供了线程安全的变量更新方法,支持整型、长整型、布尔型、数组及对象属性的原子修改。结合`volatile`关键字,可以实现多线程环境下共享变量的安全修改。
|
2月前
|
Java 开发者
Java 面向对象编程
总之,Java 的面向对象编程为开发者提供了一种有效的编程范式,帮助他们构建出高质量、可维护的软件系统。理解和掌握面向对象的概念和原则是成为优秀 Java 开发者的重要基础。
204 63
|
2月前
|
Java Android开发
Eclipse 创建 Java 包
Eclipse 创建 Java 包
41 1
|
3月前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
138 0
Java/Spring项目的包开头为什么是com?
|
4月前
|
Java API 数据处理
Java 包(package)的作用详解
在 Java 中,包(package)用于组织和管理类与接口,具有多项关键作用:1)系统化组织代码,便于理解和维护;2)提供命名空间,避免类名冲突;3)支持访问控制,如 public、protected、默认和 private,增强封装性;4)提升代码可维护性,实现模块化开发;5)简化导入机制,使代码更简洁;6)促进模块化编程,提高代码重用率;7)管理第三方库,避免命名冲突;8)支持 API 设计,便于功能调用;9)配合自动化构建工具,优化项目管理;10)促进团队协作,明确模块归属。合理运用包能显著提升代码质量和开发效率。
366 4
|
4月前
|
Java 数据安全/隐私保护
Java 包(package)的使用详解
Java中的包(`package`)用于组织类和接口,避免类名冲突并控制访问权限,提升代码的可维护性和可重用性。通过`package`关键字定义包,创建相应目录结构即可实现。包可通过`import`语句导入,支持导入具体类或整个包。Java提供多种访问权限修饰符(`public`、`protected`、`default`、`private`),以及丰富的标准库包(如`java.lang`、`java.util`等)。合理的包命名和使用对大型项目的开发至关重要。
235 2
|
5月前
|
Java Maven 数据库
|
5月前
|
Java
Java应用结构规范问题之在biz层的convert包实现转换的问题如何解决
Java应用结构规范问题之在biz层的convert包实现转换的问题如何解决
|
14天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
68 17
|
25天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者