Java.next:第二部分——与Java互操作

  [color=blue]原文地址[/color]:[url=http://blog.thinkrelevance.com/2008/8/12/java-next-2-java-interop]Java.next #2: Java Interop[/url]
  [color=blue]翻  译[/color]:[url=http://eastsun.iteye.com]Eastsun[/url]
  本文是Java.next系列的第二部分。在这一部分,我们来看Java.next语言如何与Java进行互操作。
  在所有这些Java.next语言中,与Java互操作都是很简单的一件事。这得归功于Java虚拟机规范,它使得JVM上的其它语言能够很容易的反射以及调用Java代码。

[color=darkblue][b][size=medium]一个Swing的例子[/size][/b][/color]
  作为与Java互操作的第一个例子,考虑通过调用Swing API创建一个应用程序,使其包含:
  [color=green]● 一个窗口
  ● 一个按钮
  ● 点击按钮时弹出一个模式对话框[/color]

  作为参照,这里先给出使用原始Java代码给出的实现:
// Java
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Swing {
public static void main(String[] args) {
JFrame frame = new JFrame("Hello Swing");
JButton button = new JButton("Click Me");

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(null,
String.format("<html>Hello from <b>Java</b><br/>" +
"Button %s pressed", event.getActionCommand()));
}
});
frame.getContentPane().add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}

  接下来,我将使用Java.next中的语言来实现这个Swing应用。对于这些代码,有两点需要注意的地方:
  [color=orange]■ 在这个例子中,我根据这些语言与Java语法差异从小到大的顺序呈现代码。这样做使得我们能从熟悉东西自然过渡到陌生的事物。
  ■ 下面这些实现并不是这些语言的最佳实践。它们被刻意简化,使得我们能将注意力集中在与Java的互操作上。在接下来的文章中,我将更多的展现这些语言的习惯用法。[/color]

Groovy的实现
  Groovy是Java.next语言中与Java最相似的,下面是Groovy的实现代码:
// Groovy
import javax.swing.JFrame
import javax.swing.JButton
import javax.swing.JOptionPane
import java.awt.event.ActionListener

frame = new JFrame("Hello Swing")
button = new JButton("Click Me")

button.addActionListener({
JOptionPane.showMessageDialog(null, """<html>Hello from <b>Groovy</b>
Button ${it.actionCommand} pressed""")
} as ActionListener)
frame.contentPane.add button

frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
frame.pack()
frame.visible = true

  与Java的实现对比一下可以发现,它们几乎一样。只不过省略了一些冗余的代码结构。Groovy版本使得我们能够忽略:
  [color=orange]◇ 分号
  ◇ 类型声明
  ◇ 大部分括号
  ◇ 属性的Getter与Setter[/color]

  Groovy版本的最大优势体现在事件监听器上,它展现了:
  [color=orange]◇ 多行字符串(使用"""界定)
  ◇ 使用${}往字符串里插入it.actionCommand
  ◇ 不需要匿名内部类,简单的传递一个匿名函数[/color]

  在[url=http://groovy.codehaus.org/Swing+Builder]SwingBuilder[/url]项目中可以看到如何用更符合Groovy习惯用法去使用Swing。
  我们可以得出一个显而易见的结论:在Groovy中与Java互操作相当简单。

[color=darkblue][b][size=medium]Scala的实现[/size][/b][/color]
  接下来,让我们看看Scala的版本:
// Scala (almost right, see below)
import javax.swing._
import java.awt.event.{ActionEvent, ActionListener}

object HelloWorld extends JFrame("Hello Swing") {
def showButtonMessage(msg: String) =
JOptionPane.showMessageDialog(null, String.format("""<html>Hello from <b>Scala</b>. Button %s pressed""", Array(msg)));

def main(args: Array[String]) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
val button = new JButton("Click Me")
button.addActionListener((e:ActionEvent) => showButtonMessage(e.getActionCommand.toString))
getContentPane add button
pack
setVisible(true)
}
}

  Scala版本与Groovy相对Java具有许多相同的优点:
  [color=orange]◇ 更少的类型声明
  ◇ 更少的分号
  ◇ 更少的括号[/color]

  我们还可以看到Scala独有的一些性质:
  [color=orange]◇ 在Scala中import通配符是_而不是熟悉的*。*号具有其它意义
  ◇ Scala能够单行引入同一个package中的多个class
  ◇ 因为我们只需要一个实例,所以我们用object声明而不是class
  ◇ 该object继承了JFrame,Scala允许我们使用内嵌的方式调用JFrame的构造函数,而不必再单独声明一个构造函数[/color]

  与Groovy一样,最大的不同是事件监听器。Scala同样允许我们简单的传入一个匿名函数,而不需要使用匿名内部类。
button.addActionListener((e:ActionEvent) => 
showButtonMessage(e.getActionCommand.toString))

  看起来很强大,只不过这儿我做了一个小小的弊。Scala是强类型语言,它不会自动将一个函数类型转换为一个ActionListener。因此上面的代码还不能被编译通过。幸运的是,Scala的隐式转换功能让我们拥有这个能力:强类型加上一个便利的类型系统。所有我们要做的是告诉Scala这个转换是合法的:

// Yes, we can
implicit def actionPerformedWrapper(func: (ActionEvent) => Unit) =
new ActionListener { def actionPerformed(e:ActionEvent) = func(e) }

  将上面的代码放到适当的位置,我们就能够在需要ActionListener的地方传入一个函数。
  已经有多个将Swing包装为Scala的项目。使用这些库,你能够书写更加简洁的代码。作为示例,你可以参看[url=http://scala.sygneca.com/code/scalagui]ScalaGUI[/url]。

[color=darkblue][b][size=medium]JRuby的实现[/size][/b][/color]
  现在来看看JRuby的情形:
include Java
import javax.swing.JFrame
import javax.swing.JButton
import javax.swing.JOptionPane
import java.awt.event.ActionListener

button = JButton.new "Click Me"
button.add_action_listener do |evt|
JOptionPane.showMessageDialog(nil, <<-END)
<html>Hello from <b>JRuby</b>.
Button '#{evt.getActionCommand()}' clicked.
END
end

frame = JFrame.new "Hello Swing"
frame.content_pane.add button
frame.default_close_operation = JFrame::EXIT_ON_CLOSE
frame.pack
frame.visible = true


  如果与之前Groovy的代码进行对比,你会发现它们几乎具有相同的特点:
  [color=orange]◇ 更少的类型声明
  ◇ 更少的分号
  ◇ 更少的括号
  ◇ 简洁的属性访问(没有getter与setter)
  ◇ 多行字符串(使用END界定)
  ◇ 使用${}往字符串里插入it.actionCommand[/color]

  相比而言,JRuby的ActionListener实现比Groovy稍微简单一点。JRuby能够自动根据block生成ActionListener:
button.add_action_listener { |evt|
# do stuff
}


  在JRuby的例子中,我依照Ruby的命名方式来使用Java方法名:
# Ruby
frame.content_pane

  Java程序员习惯Camel命名方式。为了便利,JRuby同时支持这两种命名方式:
# Groovy, Scala, or JRuby
frame.contentPane

  由于Ruby语言的灵活性,鼓励试验不同的语法与Java交互,可以参看[url=http://jira.codehaus.org/browse/JRUBY-903]JRUBY-903[/url]以了解相关历史。如果想了解更符合JRuby习惯用法的Swing使用方式,可以看[url=http://ihate.rubyforge.org/profligacy]Profligacy [/url]项目。
  结论:在JRuby中,与Java互操作很简单。

[color=darkblue][b][size=medium]Clojure的实现[/size][/b][/color]
  这儿是Clojure的版本:
; Clojure 
; Clojure
(import '(javax.swing JFrame JButton JOptionPane))
(import '(java.awt.event ActionListener))

(let [frame (JFrame. "Hello Swing")
button (JButton. "Click Me")]
(.addActionListener button
(proxy [ActionListener] []
(actionPerformed [evt]
(JOptionPane/showMessageDialog nil,
(str "<html>Hello from <b>Clojure</b>. Button "
(.getActionCommand evt) " clicked.")))))

(.. frame getContentPane (add button))
(doto frame
(setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
pack
(setVisible true)))

  Clojure是一种Lisp方言,因此其语法与其它几种有着本质上的不同。这一点就得花上几个小时来讨论,但我们现在的焦点是与Java的互操作,所以我将这一点留给这系列以后文章来讨论。现在,让我们把注意力放到与Java互操作上来。
  导入Java类是件很容易的事。import之后跟着一串参数,第一项是package,其余的是要导入到当前名字空间的class。注意,这样允许我们在一行中导入多个class。
(import '(javax.swing JFrame JButton JOptionPane))

  创建一个Java实例也很简单,使用(class. &args)的形式:
(JFrame. "Hello Swing")

  有多种途径来调用Java类中的方法。你可以使用(.methodName obj &args)的方式来调用单个方法。对于静态方法,使用(class/method &args)的方式:
(JOptionPane/showMessageDialog nil "A message")

  在Java中,可以通过x.y().z()的方式使用链式调用。在Clojure中你可以使用(.. x (y) (z))的方式:
(.. frame (getContentPane) (add button))

  最后的三个方法调用都是在frame对象上。使用Clojure的doto,你能够在一个对象上执行多次操作并避免每次都要重写这个对象:
(doto frame
(setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
pack
(setVisible true)))

  与其它几个例子一样,事件监听器是最有趣的部分。在Clojure中,proxy能够动态创建Java实例,并允许你实现所需的接口与方法。
(proxy [ActionListener] []
(actionPerformed [evt] {do stuff here...}))

  同JRuby一样,相对Groovy这个解决方案更具有普适性,同时需要使用更多的语法。同样,你能够构建自己的语法结构。
  结论:在Clojure中与Java互操作很简单。

[color=darkblue][b][size=medium]结论[/size][/b][/color]
  在上面的例子中,我演示了Java.next可以方便的与Java互操作。每一个例子都使用了比Java更少的代码来操作Swing库。更重要的是,Java.next的版本抓住了问题的本质并简化了形式。
  与Java的无缝衔接并不是衡量Java.next语言的首要标准,因为它们都做得很好。这里并没有体现出这些语言在复杂情形下的表现,但我认为它们与Java互操作的问题已经得到了根本的解决。
  Java.next系列的前两篇文章中,我采用了接近Java语言的风格来展示Java.next语言的特性。有了这些基础,是时候去使用Java.next各自的习惯用法了。在本系列文章接下来的部分,我们将会看到Java.next语言如何支持领域特定语言。
SXU-软件项目管理-朱少民-第九章 项目监控与控制 第十章 项目收尾 附相关习题 软件项目管理-朱少民-第九章 项目监控与控制 附相关习题 阅读详情

相关推荐

数学建模传染病模型_【数学建模】之传染病模型

点击【拇指笔记】,关注我的公众号。SE模型缺点:没有考虑接触到的人中还有一部分病人,所以所有人并不会全部被感染。建立模型:已感染人数(病人)每个病人每天有效接触(足以使人致病)人数为根据(1)(2)可以建立模型:等式两边同时除以\Delta t由导数定义有同时,取\Delta t = 1天由(1)(5)两式可得最终的模型:Logistic模型缺点:区分已感染者(病人)和未感染者(健康人)...

weixin_39590453的博客 2228

Graph RAG:融合结构化与非结构化数据的跨源关联推理

图检索增强生成(Graph RAG)是一种将知识图谱作为语义索引层、协同向量检索实现精准推理的技术范式。其核心原理在于利用图谱建模实体、关系与属性,解决传统RAG在跨表关联、逻辑嵌套和实体指代一致性上的结构性失明问题。技术价值体现在高准确率(91%)、强可解释性(带来源标注的答案)与生产级稳定性(日均12TB处理)。典型应用于多源异构数据融合场景,如ERP+CRM+文档库联合查询,尤其适合需验证性结论的金融风控、SaaS客户分析与企业知识管理。本文聚焦Graph RAG中entity linking与gra

culiao2169的博客 428

STM32鱼塘水质监测系统设计与实现

物联网技术在农业领域的应用正逐步深入,其中传感器网络作为关键基础设施,通过实时数据采集与传输实现环境监测。基于STM32微控制器的嵌入式系统因其高性能和低功耗特性,成为物联网终端设备的理想选择。该系统通过DS18B20水温传感器、PH传感器和浊度传感器组成的多参数检测网络,配合4G通信模块实现水质数据的远程监控。在农业物联网场景中,这种解决方案不仅大幅降低了传统人工检测的成本,更能通过实时预警有效预防养殖损失。本文介绍的鱼塘水质监测系统正是这一技术的典型应用,展示了如何通过STM32和常见传感器构建高性价比

weixin_42173218的博客 621

clojure 新手指南(10):与java交互

clojure是基于jvm的语言,就是说clojure会被编译成字节码被jvm执行。但是clojure能做的可不仅仅是被编译成字节码,它提供了一套API让用户与java交互。因此clojure可以直接调用java世界中那些丰富庞大的优秀库了。 数据&转换 =>12....

chuangong2592的博客 301

螺丝锁付系统软件设计 C# Winform

视觉螺丝锁付系统软件设计 C# Winform ,这是其中通信子模块设计

weixin_42522973的博客 340

ETL数据集成案例

一个典型的ETL数据集成案例是将多个来源的数据合并成一个数据集。假设有一个公司,该公司使用一些不同的系统来存储不同部门的数据,例如销售数据存储在一个CRM系统中,财务数据存储在一个ERP系统中,人力资源数据存储在一个HR系统中。为了更好地进行报告和分析,该公司决定将所有这些数据集成到一个数据仓库中。以下是实现这一目标的ETL过程的步骤:提取(Extract):首先,需要从每个系统中提取所需的数据。每个系统可能有不同的数据格式和结构,因此需要编写不同的提取程序或查询来提取数据。

runqu的博客 948

Clojure 与 Java 互操作

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33932129的博客 190

lammps教程:ovito免费输出高清图片方法

基本原理是调用ovito软件包中的TachyonRenderer模块,该模块可实现Tachyon渲染,达到和ovito 2.9 Tachyon完全相同的效果。这种方法在后来的ovito版本中已经不能使用,但是ovito 2.9版本在后处理方面功能较少,使用起来也不是特别方便。在之前的推文中,曾介绍过使用ovito 2.9版本更换Tachyon渲染器实现高清图片的输出。这个方法只需要配置ovito模块即可,完全免费,不需要购买ovito pro版。具体的配置参数可到ovito官网查询。大家好,我是小马老师。

lammps_jiayou的博客 2770

【Clojure】Clojure与Java的互操作形式

如何在Clojure中使用Java的函数库

古明地觉<如是说>:: 1132

半导体设备系列(2) 半导体设备与工厂控制仿真器Demo编写

基于C/S架构用C++编写半导体设备仿真器与工厂控制仿真器

追赶时代的博客 610

QGis二次开发 —— 2、第一个程序 - 加载栅格tif与矢量shp文件(附源码)

QGis二次开发 —— 2、第一个程序 - 加载栅格tif与矢量shp文件(附源码)

1100

【Java基础】Scanner中next与nextLine区别

Scanner概念 scanner可以用来获取用户的输入,八个基本数据类型除字符外都可以输入,另外输入字符串有两种方式next与nextLine。接下来介绍他们的区别。 1.next与nextLine的区别 1.1 区别一 String st1 = scanner.nextLine(); String st2 = scanner.next(); S...

weixin_43287478的博客 4898

Android车载蓝牙开发全攻略:从基础到高级优化

本文系统介绍了Android车载蓝牙开发的核心技术与实践指南。文章首先阐述了蓝牙在智能汽车中的关键作用,包括免提通话、音频流媒体等应用场景。随后详细解析了蓝牙协议基础,重点介绍了HFP、A2DP等车载常用协议。开发实战部分提供了设备发现、连接、数据传输的完整代码示例,并融入多线程和内存优化技巧。通过真实车载案例,展示了启动时间、流畅度和资源使用的优化策略。最后针对面试需求,提供了专业的技术问答,涵盖蓝牙开发全流程。全文紧密结合Android车载开发职位要求,为开发者提供了一套完整的蓝牙技术解决方案。

郑伟强dev的专栏 119

Java中next()、nextLine()以及nextInt()

java键盘录入,Scanner类的方法使用与注意事项

tuoniaoxs的博客 1万+

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java中Scanner类中next与nextLine的区别

1、next的意思是接受文字(有效文字),next不接收空格回车以及Tab。(当你输入空格回车Tab的时候接收就会终止,并不会存入到String 变量中去)特别的情况:当在输入的时候先输入了几个空格然后再输入String中内容得时候String变量实际接受的是空格后面的内容,并没有接受前面输入的空格,这部分叫做有效输入。 public static void main(String[]args){ Scanner scanner = new Scanner(System.in); System.out.pr

qq_48783543的博客 2681

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Java中next()与nextLine()详细解析

Java中中next与nextLine详细解析1. next()用法2. nextLine()用法3. 实例分析 1. next()用法 next()一定要读取到有效字符后才可以结束输入,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符next()方法会自动将其去掉,只有在输入有效字符之后,next()方法才将其后输入的空格键、Tab键或Enter键等视为分隔符或结束符。 简单地说...

TingtingYang 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

对Java实现单链表中.next的解释

Q: 问题引入: 我们在用Java实现单链表时, 也许有人会疑惑Java又没有指针,是如何存储链式关系的呢? 又或是有这种疑惑, Java实现中的这种node.next写法是如何移动链表的 A: 首先,Java中虽然没有指针但是有引用啊. Java的眼里,万物皆对象,对象之间靠引用关系联系在一起. 在单链表的实现中, 我们经常会写一个Node类作为内部类供LinkedList(链表类)使用, 其中有一个Node类的变量list用于存储下一个结点的位置(即list持有了到下一个结点的引用). 所

菜菜的大数据开发の路 7922

next在java中_java中next()与nextLine()有什么区别

首先我们知道Java中Scanner类中的方法next()()和next()Line()都是用来获取用户输入的。(推荐教程:java入门教程)我们来看看二者的区别:next()不会获取字符前/后的空格/Tab键,只获取字符。开始获取字符(字符前后不算)直到遇到空格/Tab键/回车截止获取;nextLine()()会获取字符前后的空格/Tab键e Y ! i a,遇到回车键截止。举例:import ...

weixin_28736355的博客 400

java .next_Java.next,无继承扩展,第1部分

存档日期:2019年5月13日 | 首次发布:2013年6月12日 Groovy,Scala和Clojure提供了许多扩展机制,而继承实际上是Java™语言的唯一选择。 本期文章着眼于类别类, ExpandoMetaClass ,隐式强制转换和协议,以作为使用Java.next语言扩展Java类的方式。 此内容不再被更新或维护。 全文以PDF格式“按原样”提供。 随着技术的飞速发展,某...

cusi77914的博客 131

random.next_Java Random next()方法与示例

random.next 随机类的next()方法 (Random Class next() method) next() method is available in java.util package. next()方法在java.util包中可用。 next() method is used to return the pseudo-random number in bits. next()方...

cumtb2002的博客 2000

Java Scanner next()方法与示例

扫描仪类的next()方法 (Scanner Class next() method) Syntax: 句法: public String next(); public String next(Pattern patt); public String next(String patt); next() method is available in java.u...

cumt951045的博客 2127

sc.next在java什么意思_sc.next() 和 nextLine 的原理

对java的Scanner类的next开头的相关类有点纠结,看了一些博客大致懂了,整理下代码事例直接参考了这位大佬的https://blog.csdn.net/long71751380/article/details/94008351. 总的原理以一段代码为例,scanner类import java.util.Scanner;public class Next {public static voi...

weixin_32899267的博客 5556

Java中.next()和.nextLine()的区别

① nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。 next()会自动消去有效字符前的空格,只返回输入的字符,不能得到带空格的字符串。 package test; import java.util.Scanner; public class SubLoop { public static void main(String[]

Android_DEPON的博客 2万+

细节!关于Java中的next与nextLine

观察几个结果,可以发现它们各自的特点和彼此之间的差异:1.next() :(1)只能读取有效字符,对有效字符出现之前的所有空格,next() 将自动忽略。(2)从有效字符出现开始,将其后输入的空格键、Tab键和Enter键等视为分隔符或结束符。(1)读取Enter键出现之前的所有字符,包括带空格的字符。(2)只能以Enter键作为结束符。其实我们可以查看API。

m0_64198455的博客 5310

Java迭代器中的next()方法

作用 next()获取当前游标指向的下一个元素并返回,游标移到下一个元素 (迭代器和数据结构中的链表一样,同理判断下一个元素位置已在存入时链接好) 注意: 先返回游标指向的下一个元素,游标再移到该位置 疑问 存入四个数据,如果next()元素获取的是下一个元素,那么为什么我输出出来的是我存入的第一个元素? 解释 Iterator(迭代器)是一个对象,其内部存储数据第一次游标指向的是一个 “空” ,第一次指向和我们存入的数据完全没有关系,使用...

NeiHan2020的博客 3698

Java中next与nextLine方法的区别

1. Java中的Scanner类中的方法next()与nextLine()都是吸取输入控制台输入的字符 ①next()方法不会吸取字符前和后的空格/Tab,只吸取字符,开始吸取字符(字符前后不算) 直到遇到空格/Tab/回车截取吸取 ②nextLine()吸取字符前后的空格/Tab键,也会吸收回车符 2. 下面对next与nextLine()方法进行测试 ①从控制台输入:abcd abcd...

二哈 4114
上一篇: Java.next:第一部分——共同点
下一篇: How To JUST DO IT
JavaSxy
博客等级 码龄21年 1粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值