访问 JVM
// kotlin本身就是jvm语言,可以无缝调用java
// groovy本身就是jvm语言,可以无缝调用java
// java本身是jvm语言, 可以直接调用java
// 可以通过 Pacakges.全类名 的方式访问java类
let sb = new Packages.java.lang.StringBuilder("M8Test")
// 内部类同样也可以通过 Pacakge.全类名 方式访问, 但是需要将 $ 改成 ., 如 android.widget.FrameLayout$LayoutParams
let LP = Packages.android.widget.FrameLayout.LayoutParams
$console.log("LayoutParams class", LP)
// 调用java对象方法使用 .
sb.append("Javascript")
$console.log(sb.toString());
let JavaTypeTester = Packages.com.m8test.script.core.impl.JavaTypeTester
// 调用java对象属性可以使用 .
$console.log(new JavaTypeTester().OBJECT_FIELD)
// 调用java静态方法使用 .
$console.log(Packages.java.lang.System.currentTimeMillis())
// 调用java静态属性使用 .
$console.log(JavaTypeTester.STATIC_FIELD)
// 实现java非功能性接口(含有多个抽象方法的接口)
JavaTypeTester.setMultiAbstractMethodInterface(
{
setInt: function (n) { $console.log("setInt" + n) },
getInt: function () {
$console.log("getInt")
return 0
}
}
)
let mami = JavaTypeTester.getMultiAbstractMethodInterface()
mami.setInt(1234)
$console.log(mami.getInt())
// 实现java功能性接口(只有一个抽象方法的接口)
// 方法1: 直接使用一个函数, 但是可能会没有代码提示并且报错, 实际上这样是没有问题的
// JavaTypeTester.setSingleAbstractMethodInterface(() => {
// $console.log("getInt")
// return 0
// })
// 方法2: 通过一个对象, 其中含有一个和java接口抽象方法名相同的函数, 这种方式有代码提示
JavaTypeTester.setSingleAbstractMethodInterface({
getInt: function () { return 0 }
})
let sami = JavaTypeTester.getSingleAbstractMethodInterface()
$console.log(sami.getInt())
-- 引入java类, 必须以 m8test_java 开头, 后面跟 java 类名
local StringBuilder = require("m8test_java.java.lang.StringBuilder")
local JavaTypeTester = require("m8test_java.com.m8test.script.core.impl.JavaTypeTester")
-- 创建java对象, 可以通过 newJavaObject 方法, 实际上会修改为 local sb = StringBuilder("M8Test")
local sb = StringBuilder:newJavaObject("M8Test")
-- 通过':'调用java对象方法
sb:append("Lua")
_console:log(sb:toString())
-- 通过'.'调用java对象属性
_console:log(JavaTypeTester().OBJECT_FIELD)
local System = require("m8test_java.java.lang.System")
-- 通过':'调用java静态方法
_console:log(System:currentTimeMillis())
-- 通过'.'调用静态属性
_console:log(JavaTypeTester.STATIC_FIELD)
-- 引入内部类, 此写法能有代码提示, 需要通过 _N_ 来替换 $ , 因为 $ 在lua中不允许, 下面的代码实际是引入 android.widget.FrameLayout$LayoutParams 内部类
local FrameLayoutLayoutParams = require("m8test_java.android.widget.FrameLayout_N_LayoutParams")
_console:log(FrameLayoutLayoutParams)
-- 实现java非功能性接口
JavaTypeTester:setMultiAbstractMethodInterface({
setInt = function(i)
_console:log("setInt" .. i)
end,
getInt = function()
_console:log("getInt")
return 0
end,
new = function() end
})
local mami = JavaTypeTester:getMultiAbstractMethodInterface()
mami:setInt(1234)
_console:log(mami:getInt())
-- 实现java功能新接口, 可以直接传递 function
JavaTypeTester:setSingleAbstractMethodInterface(function()
_console:log("getInt")
return 0
end)
local sami = JavaTypeTester:getSingleAbstractMethodInterface()
_console:log(sami:getInt())
<?php
// 通过 use 导入java类, 通过"m8test_java\全类名"的方式
use m8test_java\java\lang\StringBuilder;
use m8test_java\com\m8test\script\core\impl\JavaTypeTester;
use m8test_java\android\view\Gravity;
use m8test_java\java\lang\System;
// 通过 new 创建java对象
$sb = new StringBuilder("M8Test");
/** @var m8test_java\com\m8test\script\core\api\console\Console $console */
// 调用java对象方法使用 ->
$sb->append("Php");
$console->log($sb);
// 调用java对象属性使用 ->
$test = new JavaTypeTester();
$console->log($test->OBJECT_FIELD);
// 调用java静态方法使用 ::
$console->log(System::currentTimeMillis());
// 调用java静态属性使用 :: 并且添加前缀 $_MJ_ , 编译后会变成 Gravity::CENTER
$console->log(Gravity::$_MJ_CENTER);
// 如果 :: 不能调用静态属性, 那么需要通过反射调用
/** @var m8test_java\com\m8test\script\core\api\reflect\Reflectors $reflectors */
$v = $reflectors->reflect("com.m8test.script.core.impl.JavaTypeTester")->getField(null, function ($f) {
$f->setName("STATIC_FIELD");
});
$console->log($v);
class MultiAbstractMethodInterfaceImpl
{
var $console;
var $i;
function __construct($p)
{
$this->console = $p;
}
function setInt($i)
{
$this->i = $i;
$this->console->log("setInt", $i);
}
function getInt()
{
return $this->i;
}
}
JavaTypeTester::setMultiAbstractMethodInterface(new MultiAbstractMethodInterfaceImpl($console));
$mami = JavaTypeTester::getMultiAbstractMethodInterface();
$mami->setInt(12345);
$console->log($mami->getInt());
// 方法一: 通过闭包(推荐)
JavaTypeTester::setSingleAbstractMethodInterface(function () use ($console) {
$console->log("closure");
return 1234;
});
$sami = JavaTypeTester::getSingleAbstractMethodInterface();
$console->log($sami->getInt());
// 方法二: 通过对象
class SingleAbstractMethodInterfaceImpl
{
var $console;
function __construct($p)
{
$this->console = $p;
}
function getInt()
{
$this->console->log("getInt");
return 0;
}
}
JavaTypeTester::setSingleAbstractMethodInterface(new SingleAbstractMethodInterfaceImpl($console));
$sami = JavaTypeTester::getSingleAbstractMethodInterface();
$console->log($sami->getInt());
# -*- coding: utf-8 -*-
# 导入java类, 使用 from import 语句, from m8test_java.全类名 import 类名,这是固定格式
# 创建 java 对象
from m8test_java.java.lang.StringBuilder import StringBuilder
sb = StringBuilder("M8Test")
# 通过 . 调用 java 对象方法
sb.append("Python")
from m8test_java.com.m8test.script.GlobalVariables import _console
_console.log(sb.toString())
# 通过 . 调用 java 对象属性
from m8test_java.com.m8test.script.core.impl.JavaTypeTester import JavaTypeTester
_console.log(JavaTypeTester().OBJECT_FIELD)
# 通过 . 调用java静态方法
from m8test_java.java.lang.System import System
_console.log(System.currentTimeMillis())
# 可以通过`.`访问静态属性
from m8test_java.android.view.Gravity import Gravity
_console.log(Gravity.CENTER)
# 如果不能通过`.`访问静态属性, 那么可以反射获取
from m8test_java.com.m8test.script.GlobalVariables import _reflectors
from m8test_java.android.widget.FrameLayout import FrameLayout
wrap_content = (_reflectors.reflect(FrameLayout.LayoutParams)
.getField(None, lambda selector: selector.setName("WRAP_CONTENT")))
_console.log(wrap_content)
# 访问java内部类可以使用 . , 必须使用'外部类.内部类'的方式调用
layout_params = FrameLayout.LayoutParams(wrap_content, wrap_content)
_console.log(layout_params)
# 使用 from import 语句同时使用 as m8test_javaxxx这样格式的, 如果在类的继承中会自动移除, 例如 class A(m8test_javaxxx) , class A(m8test_javaxxx.yyy.zz) 会被替换为 class A()
from m8test_java.com.m8test.script.core.impl.JavaTypeTester import JavaTypeTester as m8test_javaHello
# 下面的类定义会被替换为 class MultiAbstractMethodInterfaceImpl(): , 下面的写法主要是为了能有代码提示
class MultiAbstractMethodInterfaceImpl(m8test_javaHello.MultiAbstractMethodInterface):
def setInt(self, i):
_console.log("setInt " + str(i))
def getInt(self):
_console.log("getInt")
return 0
# _java.proxy用于将python对象映射为java接口对象的实现类, 也就是第二个参数中指定的接口数组
from m8test_java.com.m8test.script.GlobalVariables import _java
JavaTypeTester.setMultiAbstractMethodInterface(_java.proxy(MultiAbstractMethodInterfaceImpl(), [
"com.m8test.script.core.impl.JavaTypeTester$MultiAbstractMethodInterface"]))
mami = JavaTypeTester.getMultiAbstractMethodInterface()
mami.setInt(1234)
_console.log(mami.getInt())
# 实现java功能性接口, 定义一个函数/lambda
def sami():
_console.log("getInt")
return 0
# 功能性接口可以直接使用函数/lambda
JavaTypeTester.setSingleAbstractMethodInterface(sami)
s = JavaTypeTester.getSingleAbstractMethodInterface()
_console.log(s == sami)
_console.log(s())
# 通过java_import导入java类
java_import 'java.lang.StringBuilder'
java_import 'java.lang.System'
java_import "com.m8test.script.core.impl.JavaTypeTester"
# 通过 new 创建 java 对象
sb = StringBuilder.new("M8Test")
# 通过.调用java对象方法
sb.append("Ruby")
jtt = JavaTypeTester.new
# 通过.调用java对象属性
$console.log(jtt.OBJECT_FIELD)
# 通过.调用java静态方法
$console.log(System.currentTimeMillis)
# 非final静态属性通过.调用
$console.log(JavaTypeTester.STATIC_FIELD)
java_import "android.os.Build"
# final静态属性通过 :: 调用
$console.log(Build::BRAND)
# 实现java非函数式接口
class MultiAbstractMethodInterfaceImpl
include JavaTypeTester.#::
MultiAbstractMethodInterface
def setInt(i)
$console.log("setInt #{i}")
end
def getInt()
$console.log("getInt")
0
end
end
JavaTypeTester.setMultiAbstractMethodInterface(MultiAbstractMethodInterfaceImpl.new)
mami = JavaTypeTester.getMultiAbstractMethodInterface
mami.setInt(1234)
$console.log(mami.getInt)
# 实现java功能行接口
JavaTypeTester.setSingleAbstractMethodInterface {
$console.log("getInt")
0
}
sami = JavaTypeTester.getMultiAbstractMethodInterface
$console.log(sami.getInt)
Last modified: 01 October 2025