JDK9,像Unix脚本一样执行Java代码

点击上方 "程序员小乐"关注, 星标或置顶一起成长

每天凌晨00点00分, 第一时间与你相约

每日英文

They always say time changes things but you actually have to change them by yourself.

人们总说时间会改变一切,但是实际上你需要自己努力去改变。

每日掏心

人生在世会受许多委屈,别因此而难过,一个人越成功,他所遭受的委屈也会越多。

来自:urlify.cn/fyiIRr | 责编:乐乐

程序员小乐(ID:study_tech)第 971 次推文  图源:百度

往日回顾:高并发系统如何做到限流,看这篇就对了!

     

   正文   

现在你多少听说一些JDK9 JShell相关的内容,这篇文章中将介绍如何使用JShell像Unix脚本一样执行Java代码。

让我们开始一个简单的例子,再进行详细的介绍:

  • 创建一个 java_shell_code.txt 的文件;

  • 在文件中写一些Java代码,并执行以下命令。你没必须声明一个Class,你可以直接写一句代码,或者创建一个方法。

java ex.jshell.extension.JShellScriptExecutor ./java_shell_code.txt

java_shell_code.txt

// java_shell_code.txt contents.

/* If you observe it does not need a class declaration.
 Using the power of jshell, we can write functions and call functions with out creating class, just like functional programming */

 // You can also include comments like above, anywhere in the script

String var1 = "Hello";

System.out.println(var1);

public int getInt1(){

    return 2;

}

public int getInt2(){

    return 4;

}

getInt1() + getInt2();

public class MyClass{

    public void sayHelloWorld(){

        System.out.println("HelloWorld");

    }

}

new MyClass().sayHelloWorld()

执行结果:

"Hello"

Hello

6

HelloWorld

详细介绍

在JDK9中提供了一个新的类 JShell.java,它属于jdk.jshell模块。我们可以使用它执行Java代码片段,或创建一个Java方法,而不用创建一个类。如果这个Java代码片段中有错误,可以通过 Snippet.status状态(只有两种状态:REJECTED、VALID)来检查。SourceCodeAnalysis是用来解析代码的,它使用分号、解析方法、或类的声明等。

下面是JShellScriptExecutor代码。你可以拷贝,并修改它。你也可以从GitHub仓库中克隆。

搜索公众号程序员小乐回复关键字“offer”获取算法面试题和答案。

https://github.com/kotari4u/jshell_script_executor

package ex.jshell.extension;
import jdk.jshell.JShell;
import jdk.jshell.Snippet;
import jdk.jshell.SnippetEvent;
import jdk.jshell.SourceCodeAnalysis;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;
/**
 * This class can execute jshell expressions in sequence
 * We can write java commands like shell script and execute it.
 * Just write commands in a way that we give in jshell and save it in a file and execute it.
 *
 * @author Hemamabara Vamsi, Kotari
 * @since 5/27/2017.
 */
public class JShellScriptExecutor {
    public static void main(String[] args){
        new JShellScriptExecutor().evaluate(args[0]);
    }
    public void evaluate(String scriptFileName){
        try(JShell jshell = JShell.create()){
          // Handle snippet events. We can print value or take action if evaluation failed.
            jshell.onSnippetEvent(snippetEvent -> snippetEventHandler(snippetEvent));
            String scriptContent = new String(Files.readAllBytes(Paths.get(scriptFileName)));
            String s = scriptContent;
            while (true) {
                // Read source line by line till semicolon (;)
                SourceCodeAnalysis.CompletionInfo an = jshell.sourceCodeAnalysis().analyzeCompletion(s);
                if (!an.completeness().isComplete()) {
                    break;
                }
                // If there are any method declaration or class declaration 
                // in new lines, resolve it.
                jshell.eval(trimNewlines(an.source()));
                // EOF
                if (an.remaining().isEmpty()) {
                    break;
                }
                // If there is semicolon, execute next seq
                s = an.remaining();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void snippetEventHandler(SnippetEvent snippetEvent){
        String value = snippetEvent.value();
        if(!Objects.isNull(value) && value.trim().length() > 0) {
          // Prints output of code evaluation
            System.out.println(value);
        }
        // If there are any erros print and exit
        if(Snippet.Status.REJECTED.equals(snippetEvent.status())){
            System.out.println("Evaluation failed : "+snippetEvent.snippet().toString()
                                +"\nIgnoring execution of above script");
        }
    }
    private String trimNewlines(String s) {
        int b = 0;
        while (b < s.length() && s.charAt(b) == '\n') {
            ++b;
        }
        int e = s.length() -1;
        while (e >= 0 && s.charAt(e) == '\n') {
            --e;
        }
        return s.substring(b, e + 1);
    }
}

module-info.java

module ex.jshell.extension{   
  requires jdk.jshell;
}

赶快试用下强大的JShell吧。

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。欢迎加入程序员小乐技术交流群,在后台回复“加群”或者“学习”即可。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

图文并茂,详细讲解UML类图符号、各种关系说明以及举例

MATLAB被禁影响升级!哈工大被曝在全国大学生数学建模竞赛中禁用MATLAB

肝完这篇 TCP/IP ,我就去面试去。

关注订阅号「程序员小乐」,收看更多精彩内容

嘿,你在看吗

一、UNIX文件系统的基本原理        UNIX采用树型目录结构,每个目录表称为一个目录文件。一个目录文件是由目录项组成的。每个目录项包含16B,一个辅存磁盘块(512B)包含32个目录项。在目录项中,第1、2字节为相应文件的外存i节点号,是该文件的内部标识;后14B为文件名,是该文件的外部标识。所以,文件目录项记录了文件内、外部标识的对照关系。根据文件名可以找到辅存i节点号,由此便得到该文件的所有者、存取权、文件数据的地址健在等信息。UNIX的存储介质以512B为单位划分为块,从0开始直到最大容量并顺序加以编号就成了一个文件卷,也叫文件系统。本次课程设计是要实现一个简单的模拟UNIX文件系统。我们在磁盘中申请一个二进制文件模拟UNIX内存,依次初始化建立位示图区,I节点区,数据块区。 二、基本要点思路         1、模拟磁盘块的实现:因为文件系统需要从磁盘中读取数据操作数据,在实现时是使用文件来模拟磁盘,一个文件是一块磁盘,在文件中以划分磁盘块那样划分不同的区域,主要有三个区域:位图区,inode索引节点区,磁盘块区。位图区我是使用一个512byte的数组存放,inode区和磁盘块区我采用一种自认为比较巧妙的方法,就是存放对象列表,之前说过,在本次实验的所有的结构都使用对象进行存储,而inode节点和磁盘块就是两个重要的数据结构,在初始化时我实例化32个inode对象和512个block对象(至于这些类的具体定义下面会提到),然后将这些对象加入各自对应的对象列表中,在存储时,使用java的对象序列化技术将这个对象数组存到磁盘中。当使用文件系统时,程序会先从磁盘文件中读取出位图数组,inode对象列表,block对象列表,之后的操作就是通过对这些列表进行修改来实现。使用这种方法可以减小存储的空间(对象序列话技术)而且不需要在使用时进行无用的查找,只要第一次初始化中将这些对象都读取出来。        2、界面的实现:在实现这个文件系统时使用了两种方案,一种是直接在java控制台来进行输入输出,因为原本想着UNIX文件系统原本也是使用的命令行语句,所以在控制台上实现也很接近。后来在老师的建议下又将整个程序重新修改,改成在UI界面上进行输入输出,这样确实界面美观舒服了不少,只不过两者用的技术很不一样,前者主要使用的是系统的输入输出流,后者使用java监听器。        3、权限的实现:在实现多用户的权限方面,我给文件和文件夹各定义了三级权限1、访问:在文件中是可以查看文件的内容,在文件夹中是可以进入该文件夹。2、修改:文件中是可以对文件进行编辑,文件夹中是可以在该文件夹中创建新的文件或目录。3、删除:顾名思义。文件或文件夹的创建者拥有最高级别的权限,只有拥有最高级权限的用户才可以给其他用户针对该文件或文件夹进行授权和授权操作。在每次对文件或文件夹进行访问修改删除操作时都会检查当前用户在该文件或文件夹所拥有的权限,只有拥有的权限大于想要实现的权限时才可以进行该操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值