知道Python语言的Google Fire项目么,我将它移植到了Java上

低资源AI部署实战:从模型优化到边缘设备集成 在人工智能技术日益普及的今天,模型部署已从云端延伸至资源受限的边缘设备。其核心原理在于通过模型压缩与优化技术,在保证精度的前提下,显著降低计算和存储开销,从而让AI能力在嵌入式系统、物联网终端等场景中落地。这一过程的技术价值在于实现了低延迟、高隐私的本地化智能,为工业质检、智能安防、消费电子等领域提供了关键支撑。其中,模型量化与TensorFlow Lite等工具链的成熟,使得开发者能够高效地将轻量级模型部署到ARM架构设备上,构建具备实时感知与决策能力的本地AI智能体,推动智能技术向更广泛、更基层的场景渗 阅读详情

640?wx_fmt=png

最近尝试了Python语言的开源命令行便捷工具库Google Fire,它是用来加速用户编写命令行程序的一个小工具库,该工具使用非常方便,节省了编写命令行程序繁琐的参数解析代码的时间。

巧用Google Fire简化Python命令行程序

但是我发现Java语言还缺少这样一个工具库,于是花了2天时间,将Google Fire移植到了Java语言上,命名为Startup。有了Startup,Java同学也可以从此不用解析繁琐的命令行参数了。

Startup项目的Github代码地址 https://github.com/pyloque/startup

安装依赖

<dependency>
    <groupId>com.github.pyloque</groupId>
    <artifactId>startup</artifactId>
    <version>0.0.1</version>
</dependency>

让Jedis秒变命令行

import java.io.IOException;

import codehole.startup.Startup;
import redis.clients.jedis.Jedis;

public class Demo {

    public static void main(String[] args) {
        Startup.shell(new Jedis());
    }

}

使用maven将程序打包成jar包文件demo.jar,接下来就可以体验命令行版本的Jedis了。

$ java -jar demo.jar
> @set codehole superhero
OK
> @get codehole
superhero
> @keys *
[codehole]
> @del codehole
1
> @sadd books str[]:java,golang,python
1
> @sadd books str[]:java,golang,python
3
> @smembers books
[python, golang, java]
> @scard books
3

我们还可以使用单行命令模式,将shell方法改成fire即可,有了fire函数,繁琐的命令行参数解析过程就可以彻底拜拜了。

Startup.fire(new Jedis(), args);  // 需要传递args参数

接下来,我们尝试一下单行命令的效果

$ java -jar demo.jar @set codehole superhero
OK
$ java -jar demo.jar @get codehole
superhero
$ java -jar demo.jar @keys "*"
[codehole]
$ java -jar demo.jar @del codehole
1
$ java -jar demo.jar @sadd books str[]:java,golang,python
3
$ java -jar demo.jar @smembers books
[python, golang, java]
$ java -jar demo.jar @scard books
3

Redis的set命令在Jedis里存在多个重载函数,很难记清楚具体有哪些参数。不过没关系,Startup提供了类自省功能,可以列出指定匹配模式的函数调用形式。

$ java -jar demo.jar ! @set
class: redis.clients.jedis.Jedis
    method: set(String arg0, String arg1, String arg2)
    method: set(String arg0, String arg1, String arg2, String arg3, int arg4)
    method: set(String arg0, String arg1)
    method: set(String arg0, String arg1, String arg2, String arg3, long arg4)
class: redis.clients.jedis.BinaryJedis
    method: set(byte[] arg0, byte[] arg1, byte[] arg2)
    method: set(byte[] arg0, byte[] arg1, byte[] arg2, byte[] arg3, int arg4)
    method: set(byte[] arg0, byte[] arg1, byte[] arg2, byte[] arg3, long arg4)
    method: set(byte[] arg0, byte[] arg1)

自省操作符是!,它连带祖先类一会自省了。当set方法有如此多时,如何调用具体哪个set方法呢?Startup使用参数数量和参数类型来匹配函数,如果有多个函数满足匹配条件,就使用第一个函数。比如现在要调用byte[]类型的set函数,我们可以这样写

> java -jar demo.jar @set byte[]:1,2,3 byte[]:10,20
OK
> java -jar demo.jar @get byte[]:1,2,3
[B@ae45eb6

因为输出是一个byte[]数组,所以显示的是它的toString()调用的结果。如果用户不满意输出效果,可以通过自定义IConsole.print方法来优化输出。

Startup.fire(Object target, String[] args, IConsole console);

细节规则

  1. 方法调用使用@前缀,如@set

  2. 字段访问使用$前缀,如$host

  3. 方法调用如果遇到同样参数数量的方法不止一个,那么在传递参数时就必须携带参数类型前缀信息,便于startup确定具体应该调用哪个方法。如@set str:codehole str:superhero,表示调用两个参数都是String类型的set方法。如果不给予参数类型提示,那么自动使用第一个找到的方法,这可能不是你想要的。

  4. startup的target参数可以是普通对象,也可以是类。比如Startup.fire(Jedis.class, args),那么后续的参数作用对象就是Jedis.class。

  5. 如果target是类,那么可以使用操作符+号对类进行实例化,后面跟着构造器的参数列表。比如Jedis有构造器Jedis(String host, int port),那么就可以这样实例化+ str:localhost int:6379

  6. 如果target是类,并且有默认构造器的话,那么如果要访问实例方法或者实例字段的话,就会对这个类进行自动实例化。如果没有默认构造器,这时候就会抛出异常。

  7. 如果某个方法返回值为void,Startup会进行特殊处理,返回调用对象自身。

  8. 自省操作符!可以使用! @显示所有方法,可以使用! $显示所有字段,如果不带参数,等价于! *列出所有的字段和方法。像Jedis类里面实例方法特别多,如果全部列出来会让人崩溃,这时可以用第三个参数maxlen,表示最多显示多少行。比如! @ 100最多显示100行方法。还可以通过模式匹配*号来查找方法,比如! @*set*匹配所有包行set字符串的方法列表。

  9. 输入exit和q可以退出命令行shell。

实例演示

下面我们使用链式调用的例子来演示Startup的强大威力。首先我们编写一个Counter类,可以对该类里面的整形字段value进行incr和decr操作。然后使用Startup对它进行shell化。同时我们定一个coeff静态变量,用于放大自增自减的效果。

import codehole.startup.Startup;

public class Demo {

    static class Counter {
        int value;
        static int coeff = 1;

        public Counter() {
            this(10);
        }

        public Counter(int value) {
            this.value = value;
        }

        public static int coeff() {
            return coeff;
        }

        public static void coeff(int c) {
            coeff = c;
        }

        public Counter incr() {
            return incr(1);
        }

        public Counter incr(int v) {
            this.value += v * coeff;
            return this;
        }

        public Counter decr() {
            return incr(1);
        }

        public Counter decr(int v) {
            this.value -= v * coeff;
            return this;
        }

        public int value() {
            return value;
        }

        public String toString() {
            return String.format("Counter(value=%d)", value);
        }

    }

    public static void main(String[] args) {
        Startup.shell(Counter.class); // 注意,这里的目标是类
    }

}

我们运行一下,体验一下Startup的神奇魅力。

自省

$ java -jar demo.jar
# 列出所有方法
> ! @
class: codehole.startup.demo.Demo.Counter
    method: value()
    method: decr()
    method: decr(int arg0)
    method: static coeff(int arg0)
    method: static coeff()
    method: incr(int arg0)
    method: incr()
# 列出所有字段
> ! $
class: codehole.startup.demo.Demo.Counter
    field: int value
    field: static int coeff
# 列出所有的incr方法
> ! @incr
class: codehole.startup.demo.Demo.Counter
    method: incr(int arg0)
    method: incr()
# 列出所有的decr方法
> ! @decr
class: codehole.startup.demo.Demo.Counter
    method: decr()
    method: decr(int arg0)
# 列出后缀为cr的方法
> ! @*cr
class: codehole.startup.demo.Demo.Counter
    method: decr()
    method: decr(int arg0)
    method: incr(int arg0)
    method: incr()

构造器

# 默认构造器
> +
Counter(value=10)
# 调用构造器Counter(int)
> + 5
Counter(value=5)
# 构造完继续获取实例字段
> + $value
10
> + 5 $value
5
# 构造完继续调用实例方法
> + @value
10
> + 5 @value
5
# 对类[访问实例字段或调用实例方法]会自动构造该类的默认实例,再回调方法或者访问实例字段
> $value
10
> @value
10

静态字段和方法

# 对类调用静态方法和对实例调用静态方法效果是一样的
> @coeff
1
> + @coeff
1
# 对类访问静态字段和对实例访问静态字段效果是一样的
> $coeff
1
> + $coeff
1
# 返回类型为void的方法会自动调整返回结果为调用对象
> @coeff 2
class codehole.startup.demo.Demo$Counter
> + @coeff 2
Counter(value=10)
> @coeff 2 $coeff
2

链式调用

> @incr @incr @incr 5 @incr 5 $value
22
> @incr 5 @decr 5 @incr 5 @decr 5 $value
10
> + @incr @incr @incr 5 @incr 5 $value
22
> + @incr 5 @decr 5 @incr 5 @decr 5 $value
10

总结

Java版本的Startup和Google Fire使用上还是有一些不一样,这个是语言的机制差别所致。但是使用上是大同小异,基本上Google Fire能做到的事,Startup都能做了,只是在使用形式上略有不同。

Startup继承了Fire的优良传统,小巧轻便没有任何依赖项,使用一行代码就把命令行的繁琐解析过程给彻底消灭了。同时还提供了Fire所欠缺的自省功能和交互式shell,用户使用Startup进行调试工作时会无比轻松。

阅读更多高级文章,关注微信订阅号「码洞」

病理组学分析系列教程1:使用Python-histolab进行病理图像预处理,tiles切片自动生成 病理图像tiles自动生成,WSI图像预处理 阅读详情

相关推荐

手把手教你用ROS2 Humble给PX4无人机写个“画圆”程序:从C++代码到Gazebo仿真全流程

本文详细介绍了如何使用ROS2 Humble和PX4飞控实现无人机圆形轨迹控制,涵盖从环境配置、Gazebo仿真到C++代码实现的完整流程。通过实战教程,读者将掌握轨迹跟踪仿真的核心技术,包括ROS2与PX4的通信接口、圆形轨迹算法设计及Gazebo仿真调试技巧。

weixin_29056781的博客 257

CentOS 7 启动Tomcat 报错 “ ./startup.sh: Permission denied” 解决方案及问题总结

一、解决方案 在apache-tomcat的bin目录下,输入 ./start.up无法启动Tomcat,显示 “ -bash: ./startup.sh: Permission denied ” 报错,然后回想起刚刚ll查看文件时,只有几个红色,其他都是白色: 但正常来说,可执行文件会显示绿色,无助的我然后盯着屏幕这堆东西看了一阵,发现属主对这个目录下所有的权限都是 rw-,也就是说可读可写不可执行,所以我使用命令chmod u+x *.sh对所有后缀为 sh 的文件赋予 x (写) 权限。(u代表文件

Awwwze的博客 5841

WPS集成DeepSeek最新教程,附详细图文,让文案生成更智能

本文将为大家详细介绍如何将 DeepSeek 功能集成到 WPS 中,通过 OfficeAI 插件,你无需进行复杂的本地部署,只需通过官网连接即可快速启用 DeepSeek 强大的 AI 功能。不论是文案生成、翻译校对,还是深度推理、决策支持,DeepSeek 都能为你提供便捷的解决方案。让我们一起来看看如何操作吧!

Java徐师兄的博客 6万+

linux 重启startup.sh,centos中startup.sh启动服务脚本

startup.sh (示例)#!/bin/bash#定义一些用户变量APP_HOME=/opt/apiWebAPP_NAME=apiWeb.warLOG_FILE=out.log#使用说明,用来提示输入参数usage() {echo "Usage: sh startup.sh [start|stop|restart|status]"exit 1}#检查程序是否在运行is_exist(){pid=...

weixin_29481259的博客 5844

DMTF相关协议(一):Redfish和SMBIOS

Redfish 是一种管理标准,使用超媒体 RESTful 接口中的数据模型表示。该模型以标准的、机器可读的模式表示,消息的有效负载以 JSON 表示。该协议本身利用了 OData v4。由于它是一个超媒体 API,因此能够通过一致的接口表示各种实现。它具有管理数据中心资源、处理事件、长时间任务和发现的机制。

weixin_44032634的博客 2267

多层下拉框_HLM多层线性模型|HLM2教程

01多层线性模型简介多层线性模型(Multilevel linear model),又称为多层分析、分层线性模型。其本质是线性模型的线性模型、回归的回归。本文主要介绍如何使用HLM6.08软件来构建两层线性模型。02案例简介水平1文件:样例数据HSB1.sav包括7185个案例和4个变量:MINORITY:种族(1=minority, 0=other)FEMALE:性别(1=femal...

weixin_35714534的博客 5620

Linux启动tomcat

用以上命令启动tomcat时没有输出启动的信息,直接就是如下的结果,这个效果跟我们一般启动的时候不一样,看的有点懵,因为以前都是启动以后很多信息输出,结果这个是这样的,就没了,也不知道有没有成功。尝试访问,发现一直在转圈,过一会才能访问成功,看来还是可以的,怎么用常见的那种方式启动呢,使用以下命令,启动tomcat时候没有控制台,想要看实时的运行日志,进入到tomcat的log下,使用命令。1、先到tomcat的目录中,找到bin文件夹,查看文件夹内容。方式一:直接启动 ./startup.sh。

while(life)++; 9276

万字详解YOLOv8网络结构Backbone/neck/head以及Conv、Bottleneck、C2f、SPPF、Detect等模块

YOLOv8是由Ultralytics开发的最先进的目标检测模型,推升了速度、准确性和用户友好性的界限。YOLO这一缩写代表“你只看一次”(You Only Look Once),通过在一次网络传递中同时预测所有边界框,提升了算法的效率和实时处理能力。相比之下,其他一些目标检测技术需要经过多个阶段或过程来完成检测。YOLOv8在流行的YOLOv5架构上进行了扩展,在多个方面提供了改进。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 14万+

巧用Startup简化Java命令行程序

最近尝试了Python语言的开源命令行便捷工具库Google Fire,它是用来加速用户编写命令行程序的一个小工具库,该工具使用非常方便,节省了编写命令行程序繁琐的参数解析代码的时间。 巧用Google Fire简化Python命令行程序 但是我发现Java语言还缺少这样一个工具库,于是花了2天时间,将Google Fire移植到了Java语言上,命名为Startup。有了Startup,Java...

weixin_34414196的博客 546

使用静态库在嵌入式系统中进行开发

静态库是一种包含预编译对象代码的文件,它可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。静态库是包含预编译对象代码的文件,可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。的静态库文件,可以在嵌入式系统的应用程序中使用它了。

ZrElixir的博客 205

uniapp - 实现手机端H5网页直播功能效果,拿到后端推流地址或播放资源后进行前端的流畅播放和画面展示功能,uniapp实时推流/拉流直播系统详细教程(提供完整示例代码,一键复制开箱即用!)

uniapp,h5网页,手机端H5网页,uniapp h5直播功能页面,uniapp直播实时推送显示,uniapp h5直播怎么做,怎么使用uniapp去实现移动端手机H5直播,h5 vue+uniapp怎么做直播,uniapp中使用videojs构建H5直播播放器,uniappH5端怎么实现直播推流,uniapp如何实现直播,直播聊天功能,h5平台端直播用什么插件,uniapp手机网页直播用什么组件插件播放器,uniapp手机H5直播播放器详细教程,直播项目,怎么使用vue+uniapp怎么做H5实时直播

✅ 精选推荐文章 8794

google firefor 历史版本下载谷歌火狐浏览器版本下载大全

https://blog.youkuaiyun.com/liuxueyi521/article/details/107292629

liuxueyi521的专栏 1190

[NoC]Outstanding和Credit的概念详解

摘要:本文详细解析了计算机体系结构中outstanding和credit两个核心概念。outstanding指已发出但未完成的请求数量,通过跟踪未决事务实现并发和乱序执行,常见于AXI总线等场景;credit则是基于信用令牌的流控机制,通过控制发送速率防止接收端缓冲溢出,多用于NoC网络。二者在目的、机制上存在差异:outstanding侧重提升并发度,credit关注流控保护。文章通过AXI协议实例和SystemC代码示例展示了二者的应用与结合方式,并探讨了在SoC设计中参数优化的方法,包括性能/资源权衡

元直的博客 2285

Python 学习 ---> 模块、pypi ( 模块库 )、添加模块路径

什么是 模块 在 Python 中,一个.py文件就是一个模块(Module)。模块的名字就是文件的名字。在模块内部,通过全局变量__name__可以获取模块名(即字符串) 模块作用 为了实现代码的复用,通常会把一些其他程序中重用的代码拿出来单独放在一个程序文件中,

freeking101的博客 3486

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

SpringBoot程序的shell控制脚本(startup.sh)

SpringBoot应用shell控制脚本

混沌世界 2502

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

java startup_Java程序启动脚本-startup.sh

#!/bin/sh#当前脚本所在的相对路径HOME=$(dirname $0)echo HOME=$HOME#当前脚本所在的绝对路径BIN_FOLDER=$(cd "$(dirname "$0")";pwd)echo $BIN_FOLDER#java命令的绝对路径JAVA="$JAVA_HOME/bin/java"export $2if [ -z "$scale" ]; thenscale=$2f...

weixin_42298105的博客 778

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

华为鸿蒙harmony4.0系统安装谷歌服务框架GMS谷歌应用商店Google Play(无需电脑操作,纯手机)

13. 打开安装的MicroG, 登录Google账号,完成后回到Googlefire,点击第二步,会让你登录你的第二个Google账户,如果需要的话就继续登录,以此类推,登录多个Google账号,需要提醒的是,Google账号只能这里登录,下面步骤不再允许登录账号。再安装Google play服务之前,会跳转“应用信息”,要求“强行停止”MicroG的运行,并点击“卸载”,完成之后才可继续安装。打开设置->系统和更新->日期和时间->关闭“自动设置”->将时间设置为2019年。下载安装包,链接私戳我发。

weixin_41710647的博客 1万+

关于LINUX权限(启动tomcat)-bash: ./startup.sh: Permission denied

关于LINUX权限-bash: ./startup.sh: Permission denied &lt;script type="text/javascript"&gt;&lt;/script&gt;&lt;script type="text/javascript"&gt;&lt;/script&gt; 在执行./startup.sh,或者./shutdown.sh的时候,爆出了Permis...

with all my passion 2619

Linux权限:提示-bash: ./startup.sh: Permission denied的解决方案

启动tomcat命令: ./startup.sh 之后提示-bash: ./startup.sh: Permission denied 原因:在Linux中,第一次启动一个新的tomcat,用户没有权限,而导致无法执行。用命令chmod 修改一下bin目录下的.sh权限就可以了 解决:在bin目录下输入: chmod u+x *.sh 这里的u 这里指文件所有者,+x 添加可执行权限,*.sh表示所有的sh文件 ...

firament的博客 1万+

彻底解决华为手机安装谷歌框架后出现未认证的弹窗问题

华为手机如何安装谷歌框架、谷歌商店,安装后如何解决未认证弹窗,带你避开所有坑!彻底解决所有问题!

Eric_Eric__的博客 4万+

linux系统使用./startup.sh提示权限不够

在tomcat/bin目录下执行:chmod u+x *.sh 再使用./startup.sh重新启动tomcat即可!

happyRX的博客 1万+

Linux下执行脚本文件出现-bash: ./startup.sh: /bin/sh^M: 坏的解释器: 没有那个文件或目录

Linux下执行脚本文件出现-bash: ./startup.sh: /bin/sh^M: 坏的解释器: 没有那个文件或目录

LZ_WuYanZu的博客 1157

LINUX权限-bash: ./startup.sh: Permission denied

执行./startup.sh,或者./shutdown.sh的时候,报:Permission denied .需要用命令:chmod 修改一下bin目录下的.sh权限。即chmod u+x *.sh 一下再运行 .sh文件。LINUX权限-bash: ./startup.sh: Permission denied。

qq_72383176的博客 1123

Linux上的环境部署

一. 环境准备 SecureCRT jdk-7u75-linux-x64.tar.gz MySQL-5.6.25-1.el6.x86_64.rpm-bundle.tar apache-tomcat-7.0.57.tar.gz 二.在linux上安装JDK 1.首先上传jdk put h://jdk-7u75-linux-x64.tar.gz (我这里是在h盘存放的,根据自己情况) 2....

老婆就是要败家 402

深入解析Tomcat启动脚本:startup.sh的工作原理与实现细节!

解析路径startup.sh首先解析自身的绝对路径,确保后续操作基于正确的目录。检查依赖检查脚本是否存在且可执行,确保启动过程能够继续。调用catalina.sh通过exec命令调用,并传递start参数,启动Tomcat服务器。启动Tomcat负责设置环境变量、加载配置并启动Tomcat。在实际生产环境中,我们可能需要自定义startup.sh脚本,以满足特定需求。通过setenv.shstartup.sh是Tomcat启动过程的关键脚本,它通过调用完成服务器的启动。通过深入分析。

weixin_39033358的博客 890

java运行startup文件_运行startup.bat的启动过程

一、前言一般启动tomcat都是找到bin目录下的startup.bat(windows)下或者startup.sh(linux下),所以要研究tomcat的启动,startup脚本是避不开的。那么下面就来看一看windows下面的startup.bat。二、bat文件要看懂startup.bat,首先得对bat文件有个基本的了解。bat文件是dos下的批处理文件。批处理文件是无格式的文本文件,这...

weixin_31614753的博客 2020
上一篇: 巧用Google Fire简化Python命令行程序
下一篇: 老钱的处女作《深入理解RPC》正式上线了
码洞
博客等级 码龄10年 41粉丝 137原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值