Java中jar包的创建和使用

Java中jar包的创建和使用

jar包的基本概念

jar包的全称是java archivejar包本质就是一种压缩包。在Java开发中一般是用来压缩类的一个包。类似C/C++中的静态库和动态库,但是又不完全是。

C/C++中的静态库和动态库是对中间文件(*.o)打包成一个二进制包。

  • 如果是静态库,则在编译可执行文件(*.exe)的时候把静态库和可执行文件编译到一起。
  • 如果是动态库,则单独编译完可执行文件后,执行可执行文件时动态加载动态库。

Java的jar包是对编译好的字节码打包到一个jar包中。jar包分为以下两类:

  • 不带主类
  • 带主类

不带主类的jar包就和C/C++的库差不多了,带主类的jar包在运行的时候就需要使用jar.exe来运行。

命令行生成jar包

不带主类

先把源文件写好,尽量使用简单点的例子,要不然容易把重心放到源文件的代码编写上了,我们这里的重点是讲jar包,不是源文件的具体功能。

我们以封装一个计算器类为例,然后把这个类打包供其他类使用。

在随便一个项目目录下创建cukor/calc文件夹。然后创建MyCalc.java文件,内容如下:

package cukor.calc;

public class MyCalc {
    // 加法
    public static int add(int... numbers) {
        int sum = 0;
        for (int i : numbers) {
            sum += i;
        }
        return sum;
    }
    // 减法
    public static int sub(int... numbers) {
        int first = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            first -= numbers[i];
        }
        return first;
    }
    // 乘法
    public static int mult(int... numbers) {
        int result = 1;
        for (int i : numbers) {
            result *= i;
        }
        return result;
    }
    // 除法
    public static int div(int... numbers) {
        int first = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            try {
                first /= numbers[i];
            } catch(Exception e) {
                System.out.println("除数不能为0,程序异常:" + e.getMessage());
            }
        }
        return first;
    }
}

上面的MyCalc应该是没问题的,就分别封装了加、减、乘、除功能的四个静态成员函数,类外不用创建对象调用,直接使用类名来调用。

然后编写一个主类来调用它,回到项目目录,创建Main.java文件,内容如下:

import cukor.calc.MyCalc;		// 导入刚刚写好的类
public class Main {
    public static void main(String[] args) {
        int result;
        result = MyCalc.add(1, 0, 3, 4);
        printResult("加法", result);
        result = MyCalc.sub(9, 32, 3, -10);
        printResult("减法", result);
        result = MyCalc.mult(4, 3, 2);
        printResult("乘法", result);
        result = MyCalc.div(4, 2, -1);
        printResult("除法", result);
        System.out.println("程序结束");
    }
    public static void printResult(String string, int result) {
        System.out.println(string + result);
    }
}

编译MyCalc.java

javac cukor/calc/MyCalc.java

编写Manifest文件:

自定义命名,但是要以.mf为拓展名,如MyCalc.mf

Manifest-Version: 1.0
Class: cukor/calc/MyCalc
Create-By: 19
  • Manifest-Version: 1.0:指定jar包的版本是1.0
  • Class: cukor/calc/MyCalc:指定jar包中包含的类
  • Create-By: 19:指定JDK版本

创建MyCalc.jar

jar -cfm MyCalc.jar MyCalc.mf cukor/calc/*.class

其中-cfm:是-c-f-m的结合简写,它们的解释可以在终端输入下面的命令查看:

jar --help

截取这几个选项的说明:

  -c, --create               创建档案。通过 -f 或 --file 指定的档案文件名
                             包含路径时,还将创建
                             缺少的父目录
  -f, --file=FILE            档案文件名。省略时, 基于操作
                             使用 stdin 或 stdout
      --release VERSION      将下面的所有文件都放在
                             jar 的版本化目录中 (即 META-INF/versions/VERSION/)
  -m, --manifest=FILE        包含指定清单文件中的
                             清单信息
  • MyCalc.jar:生成的jar包的名字
  • MyCalc.mf:jar包清单文件,刚刚写好的
  • cukor/calc/*.class:实际打包的类,其中*表示通配符,也可以指定全部名字

如果程序没有报错的话,查看当前项目目录应该得到下面的结果,如果报错了就检查一下那里不一样,并更改。

PS D:\myCoding\Terminal\Java\TestJar> ls

    Directory: D:\myCoding\Terminal\Java\TestJar

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----    2023/4/16 星期日    12:31                cukor
-a---    2023/4/16 星期日    12:38            526 Main.java
-a---    2023/4/16 星期日    12:48           1334 MyCalc.jar
-a---    2023/4/16 星期日    12:43             64 MyCalc.mf

如果使用压缩软件打开MyCalc.jar会看到下面的结果,这里以Bandzip为例。

请添加图片描述

请添加图片描述

请添加图片描述

这个时候可以把cukor文件夹删掉。因为我们已经打包了,为了防止Main.java编译的时候会依赖cukor文件夹,所以我们需要把它删除或者移动到其他位置。

然后编译Main.java

javac -cp ".;MyCalc.jar" Main.java

然后运行Main.class

java -cp ".;MyCalc.jar" Main
  • -cp ".;MyCalc.jar":表示临时使用classpath环境变量为:".;MyCalc.jar",jar包是一定要带上的要不然会报找不到类的错误。而且是编译和运行都要带上。如果依赖多个jar包就顺着写然后使用逗号分隔就可以了。例如".;MyCalc.jar;Test.jar;Test2.jar;".

输出结果:

加法8
减法-16
乘法24
除法-2
程序结束

如果Main.java中使用了package,那么在运行的时候一定要带上包名。

带主类

新建一个项目(新的文件夹下)。防止和上面的混乱。

上面的jar包是不带主类的,下面就把主类也打包到jar包中,然后使用jar命令来运行,而不是用java

代码还是上面的,只是我们现在的MyCalc2.jar要包含原来的MyCalc.class和主类Main.class

可以把上一个项目的文件直接拷贝过来。然后用解压软件把MyCalc.jar解压,然后只保留需要的cukor/calc/MyCalc.class。路径也是保留的,要不然Main.java编译不了。

编译Main.java

javac Main.java

如果报错了,说找不到类,那肯定是没有保留住cukor文件夹及其子目录,因为Main.java中导入包的代码是import cukor.calc.MyCalc;,那包路径没有保留当然是报错的。

然后写Manifest文件(.mf为后缀):

Manifest-Version: 1.0
Main-Class: Main
Create-By: 19

创建MyCalc2.jar

jar -cfm MyCalc2.jar manifest.mf Main.class cukor/calc/*.class

然后运行MyCalc2.jar

java -jar MyCalc2.jar

输出结果:

加法8
减法-16
乘法24
除法-2
程序结束

VSCode生成jar包

VSCode适合小型一点的java项目,大一点的项目需要不太合适,使用VSCode来封装jar包的过程中也可以学习到关于jdk命令行的一些小知识,虽然好像也没什么用,但是了解一下还是可以的。

首先需要在VSCode里安装Java拓展包插件:

请添加图片描述

然后创建Java项目:

请添加图片描述

项目类型:(一般项目即可)
请添加图片描述

然后跳出一个选择文件夹的框,选择一个文件路径就可以,这个是你的当前项目的路径。

项目结构:

请添加图片描述

  • .vscode:放置项目属性设置,包括生成路径、classpath的路径、jar包的路径。
  • bin:字节码的输出路径
  • libjar包的存放路径
  • src:项目源文件路径
  • App.java:默认生成的主类源文件
  • Readme.md:项目说明文档

可以打开Readme.md查看当前项目结构的具体信息。

那现在开始写代码:其实还是用上面的代码。

  • App.java
import cukor.calc.MyCalc;		// 导入刚刚写好的类
public class App {
    public static void main(String[] args) {
        int result;
        result = MyCalc.add(1, 0, 3, 4);
        printResult("加法", result);
        result = MyCalc.sub(9, 32, 3, -10);
        printResult("减法", result);
        result = MyCalc.mult(4, 3, 2);
        printResult("乘法", result);
        result = MyCalc.div(4, 2, -1);
        printResult("除法", result);
        System.out.println("程序结束");
    }
    public static void printResult(String string, int result) {
        System.out.println(string + result);
    }
}
  • MyCalc.java
package cukor.calc;

public class MyCalc {
    // 加法
    public static int add(int... numbers) {
        int sum = 0;
        for (int i : numbers) {
            sum += i;
        }
        return sum;
    }
    // 减法
    public static int sub(int... numbers) {
        int first = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            first -= numbers[i];
        }
        return first;
    }
    // 乘法
    public static int mult(int... numbers) {
        int result = 1;
        for (int i : numbers) {
            result *= i;
        }
        return result;
    }
    // 除法
    public static int div(int... numbers) {
        int first = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            try {
                first /= numbers[i];
            } catch(Exception e) {
                System.out.println("除数不能为0,程序异常:" + e.getMessage());
            }
        }
        return first;
    }
}

VSCode不需要我手动编译,当我保存文件的时候自动帮我编译了。

请添加图片描述

那就直接生成jar包吧。

通过控制面板找项目视图

请添加图片描述

左下角有项目视图

请添加图片描述

然后生成jar包。

请添加图片描述

带主类的就选App,不带主类就选<without main class>

现在选择第二个,第一个自己试了,都是一样的操作,只是等下生成的Manifest文件的内容不一样而已,不一样的就一行。但打包到jar包中的结果是一样的,就是选<without main class>也会把App.class包含进去。

打包成功VSCode右下角就出现下面的弹框。

请添加图片描述

在当前项目目录下就生成了TestCode.jar,这个名字和项目名称相同。

请添加图片描述

然后可以删除或者移动cukor/calc/MyCalc.java,把bin目录下的文件都删除了。把TestCode.jar移动到lib文件夹下。

程序没有报错,并且重新自动编译好了新的App.class

请添加图片描述

直接运行,没有任何问题。

请添加图片描述

注意,这里不要自己手动运行,因为VSCode在自动帮我们编译的时候使用了--enable-view选项,所以在运行的时候如果是我们自己手动运行,那么很容易漏掉这个选项,导致报错,而VSCode自带的运行就会自己加上这个选项所以不会报错。

其中'@C:\Users\ADMINI~1\AppData\Local\Temp\cp_ab0491xg1nsgvk4j00lx26h1u.argfile'是一个超链接,会连接到本地的文件夹打开对应的文件,读取文件中的内容,并把内容替换这个超链接。

注意,这个超链接链接到的文件是在Temp文件夹下的,所以其实可以随便删除,这个只是一个临时文件。

ctrl+鼠标左键单击那个超链接,打开可以看到是下面的内容:

 --enable-preview -XX:+ShowCodeDetailsInExceptionMessages -cp "D:\\myCoding\\Terminal\\Java\\Test\\TestCode\\bin;d:\\myCoding\\Terminal\\Java\\Test\\TestCode\\lib\\TestCode.jar"

除了路径和我的不一样之外,其他的应该是一样的。可以看到,VSCode在运行的时候传递给java.exe的参数中就有刚刚提到的--enable-preview。是因为我使用的JDK是19的版本,并不是一个长期支持的版本,所以就会有这个选项,其实如果在编译的时候不加这个--enable-preview选项,也是可以的,但是在运行的时候就不能加。即对于--enable-preview选项要么编译运行都加要么就都不要加。-XX:+ShowCodeDetailsInExceptionMessages表示的是如果程序有什么异常的就会把对应的异常信息打印到控制台上。-cp就是用来临时改变classpath环境变量的,因为我们用到了我们自己的jar包,所以一定要把我们的jar包路径配置到classpath环境变量中。

IDEA生成jar包

创建好项目后创建源文件。

  • Main.java
package TestCode;

import TestCode.cukor.calc.MyCalc;

public class Main {
    public static void main(String[] args) {
        int result;
        result = MyCalc.add(1, 0, 3, 4);
        printResult("加法", result);
        result = MyCalc.sub(9, 32, 3, -10);
        printResult("减法", result);
        result = MyCalc.mult(4, 3, 2);
        printResult("乘法", result);
        result = MyCalc.div(4, 2, -1);
        printResult("除法", result);
        System.out.println("程序结束");
    }

    public static void printResult(String string, int result) {
        System.out.println(string + result);
    }
}
  • MyCalc.java
package TestCode.cukor.calc;

public class MyCalc {
    // 加法
    public static int add(int... numbers) {
        int sum = 0;
        for (int i : numbers) {
            sum += i;
        }
        return sum;
    }

    // 减法
    public static int sub(int... numbers) {
        int first = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            first -= numbers[i];
        }
        return first;
    }

    // 乘法
    public static int mult(int... numbers) {
        int result = 1;
        for (int i : numbers) {
            result *= i;
        }
        return result;
    }

    // 除法
    public static int div(int... numbers) {
        int first = numbers[0];
        for (int i = 1; i < numbers.length; i++) {
            try {
                first /= numbers[i];
            } catch (Exception e) {
                System.out.println("除数不能为0,程序异常:" + e.getMessage());
            }
        }
        return first;
    }
}

我当前的项目目录:

请添加图片描述

然后开始创建jar包。

文件->项目结构->

请添加图片描述

工件->加号->JAR->来自具有依赖项的模块中。

找主类:

请添加图片描述

请添加图片描述

前面只是一堆设置,下面才是构建生成jar包,IDEA比较麻烦。

请添加图片描述

请添加图片描述

然后在out路径下就生成了Demo.jar包。

请添加图片描述

但是,使用解压工具打开会发现,它把所有的软件包都打包进去了。。。。

请添加图片描述

第二次选择空项目。

请添加图片描述

请添加图片描述

请添加图片描述

然后同样的方式构建jar包。但是下面要选择test.jar.

请添加图片描述

然后生成了test.jar.

请添加图片描述

使用解压软件打开看一下。

没有任何区别。然而更麻烦了。

在这里插入图片描述

好了,关于jar包的创建和使用就说这么多,eclipse的就自己玩吧。同样的道理,其实理解了命令行版本的,图形化版本的都好理解。

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值