zoukankan      html  css  js  c++  java
  • Java中的包学习笔记

    一、总结

    1.引入包的概念的原因和包的作用
    比如有多个人开发一个大型程序,A定义了一个Math.java类,B也定义了一个Math.java类,它们放在不同目录,使用的时候也是用目录来区分,
    包实际上就是一个文件夹(可以含有多级子目录)路径名。包的作用就是用来区分同名的类(冲突问题)。

    2.使用步骤
    package:
    Java源文件中:package 包名.子包名;eg: package a.b.c.d;
    编译命令:javac -d <dir> <file.java> 表示在<dir>目录下生成包
    执行方法:java 包名.子包名.类名

    import:
    使用不同的包时要import
    public class可以被外包访问,class只能在本包中访问 ###???###
    格式:java文件中 import 包名.子包名.类名; 这是手工导入这个类,也可以 import 包名.子包名.*;让JVM自动加载需要的类。

    jar:
    生成:jar -cvf <file.jar> <dir>
    查看:jar -tvf <file.dir>
    解压:tar -xvf <file.dir>

    3.包就是一个文件夹路径,所以也可以在包下创建类

    4.把程序交给用户的时候需要把Pack.class和整个包(a目录)交给他,这样比较麻烦,可以使用jar打包一下. jar -help 查看帮助。

    5.压缩成.jar文件后删除a目录后java Pack运行报错“NoClassDefFoundError”,用户找不到这个类了,我们需要设置一个环境变量CLASSPATH,
    它有两个作用,一个是在编译的时候来查找源代码,另一个作用是在执行时查找类的路径。
    $ export CLASSPATH=.:my.jar //使用‘:’控制若在当前目录下找不到就去my.jar下面找
    然后删除包目录再编译javac Pack.java就可以成功了,执行javac Pack也是成功的。

    此时$export CLASSPATH=.将其设置为默认值,然后重新执行java Pack时就又报错了,说明是实时更加CLASS_PATH的值查询的。

    如果以后遇到报找不到类的时候就可以考虑是否要设置CLASSPATH。它可以指定目录,也可以指定压缩包。


    6.javac -help指明使用-verbose可以在编译时输出更多信息,加上它后可以看它去哪里查找那些源代码[search path for source files: .,my.jar]。
    显示出的那些目录就是通过CLASS_PATH指定的。
    $ javac Pack.java -verbose

    二、例子

    1. 编译生成包

    /*file: Pack.java*/
    
    package a.b.c.d; //要把编译生成的class文件放在指定目录下的a/b/c/d/目录下
    
    public class Pack {
        public static void main(String args[]) {
            System.out.println("Hello, world!");
        }
    }
    
    /*
    编译执行:
    $ javac -d . Pack.java
    $ java a.b.c.d.Pack
    */

    2.区分使用不同包中的函数

    $ tree
    .
    ├── lisi
    │    └── Math.java
    ├── Pack.java
    └── zhangsan
        ├── Math.java
        └── Print.java

    zhangsan/Math.java

    package a.b.c.d2;
    
    public class Math {
        public static int sub(int x, int y) {
            return x - y;
        }
    
        public static int add(int x, int y) {
            return x + y + 2;
        }
    
    }

    zhangsan/Print.java

    package a.b.c.d2;
    
    public class Print {
        public static void printInfo() {
            System.out.println("package: a.b.c.d2");
        }
    
    }

    lisi/Math.java

    package a.b.c.d1;
    
    public class Math {
        public static int add(int x, int y) {
            return x + y;
        }
    }

    Pack.java

    import a.b.c.d1.*; //a.b.c.d1.Math
    import a.b.c.d2.*; //若这里都直接写a.b.c.d2.Math会报错:Math already defined in a single-type import
    
    
    public class Pack {
        public static void main(String args[]) {
            /* add */
            System.out.println(a.b.c.d1.Math.add(1,2)); //调用指定包的函数
            System.out.println(a.b.c.d2.Math.add(1,2));
    
            /* sub */
            System.out.println(a.b.c.d2.Math.sub(1,2));
    
            a.b.c.d2.Print.printInfo(); //调用包下面的Print类的printInfo方法
            Print.printInfo(); //也可以这样调用,如果没有同名的类的话就不需要使用包来限制它
        }
    }

    编译执行

    javac -d . lisi/Math.java
    javac -d . zhangsan/Math.java
    javac -d . zhangsan/Print.java
    
    javac Pack.java
    javac Pack

    打包的例子略。

    2.第二个例子

    /*A.java*/
    package a.b.c;
    
    public class A {
        public int count;
    
        protected void print_a() {
            System.out.println("print_a");
        }
    }
    /*B.java*/
    package d.e.f; /*package必须要在import前面*/
    import a.b.c.A;
    
    public class B extends A {
        public int count;
    
        public void print_b() {
            super.print_a(); /*处于不同的包中子类也可以访问父类的protected成员*/
            System.out.println("print_b");
        }
    }
    /*Test.java*/
    package m.n;
    
    import a.b.c.A;
    import d.e.f.B;
    
    public class Test {
        public static void main(String args[]) {
            B b = new B();
            b.print_b();
        }
    }
    /*编译步骤*/
    export export CLASSPATH=./
    javac -d ./ A.java
    javac -d ./ B.java
    javac -d ./ Test.java
    
    $ tree
    .
    ├── a
    │   └── b
    │       └── c
    │           └── A.class
    ├── A.java
    ├── B.java
    ├── d
    │   └── e
    │       └── f
    │           └── B.class
    ├── m
    │   └── n
    │       └── Test.class
    └── Test.java
    
    /*运行和结果*/
    $ java m.n.Test 
    print_a
    print_b
  • 相关阅读:
    Winfrom 减少控件重绘闪烁的方法
    Blazor client-side Preview 预览版 如何调试 Debug
    实用,Windows后台守护进程iNeuDaemon发布。Linux操作系统下使用使用supervisor
    RabbitMQ消息队列之Windows下安装和部署(一)
    Angularjs接收服务端的布尔值
    python基础教程:浅谈python for循环的巧妙运用(迭代、列表生成式)
    Excel合并数据查找函数VLOOKUP()一直显示最后一行数据或者一直报错的解决方法
    RHCE(一)NFS服务详解——搭建与配置
    [WPF 自定义控件]在MenuItem上使用RadioButton
    EF CORE中复杂类型的映射
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10398883.html
Copyright © 2011-2022 走看看