[jsでjava jvmを書く]1.jsはjava beanの属性と基本タイプを解析する
先日、jsが大部分のjvm機能を実現したと海外で報道されたのを見て、最近もjsでjvm機能を実現する方法を考えています.
後で考えてみると、まだ実行可能で、実はjsでjvm仕様を実現するだけで、例えばjavaにとってSystem.out、println(「test」)があります.このような文が現れるとコンソールに「test」と出力されます.
この文法はjavascriptつまり
var System ={};
System.out={
println:function(val){
//具体的な機能を実現
alert(val);
}
}
Javaのjava.lang.Stringのように 上術方式を参照して実現することもでき、apiはこの方式で徐々に実現する.
それはjava beanオブジェクトをどのように変換するかについても今日お話しするポイントであり、java beanをjavascript objectに変換する方法ではapiが実現してもjava言語を実行させる環境はありません.
次に、変換方法について説明します.
まず簡単なjava beanとjavascript objectの違いを見てみましょう
では、解析を始めます
解析プロセス:
1.クラス名の抽出
Java仕様によると、クラスの名前はclass name{...}でなければならないことがわかります.前に修飾子があり、内部クラスもそうです.
このような内容に正則的に一致するように書くことができます.最初に現れた{の文字列に一致し、classnameを抽出するだけです.
それとも正則(public|private|protected)?s*classs*w+?{ または class(.+?){ ルールに合致するすべてのデータをマッチングし、内部クラス名もマッチングします.
具体的なコードはClass.getName()を参照してください.
2.属性の抽出
正規の方法で処理することもできます.javaメンバー変数の特徴:修飾子(有無可能)+変数タイプ+メンバー名+";"(注意後にもう一つ;終了子)
ローカル変数との違いは戻り値タイプとmethodの違いは(){...}コードクリップがないことです
だから属性の抽出は正則を採用することができます
/(private|public)?\s+(void|int|float|boolean|double|String)[A-Za-z0-9|\s|_]+;
属性を処理する過程で、javaのintタイプのメンバー変数のデフォルト値が0などの変数タイプを処理する必要があります.
そこで,メンバ変数タイプに対応するvar Type={
"int":0,
"boolean":false
}
「public int a;」という文字列に一致したと仮定します.
そして私たちはこのように処理することができます
classname.prototype.a =Type[int];
3.メソッドの抽出(メイン関数mainメソッドの処理を先に紹介)
methodの抽出は比較的面倒な点であり,{}ラベル閉鎖の処理を考慮する必要がある.
mainメソッドもメインエントリ関数ですが、存在する場合は中身を実行します.public void static main(String[]args)……{....}でなければなりません.また、1つのクラスに1つしかありません.期間中argsはパラメータエントリで、argumentsに対応します.
対応するjsに変換すると
classname.prototype.ininv = function(){....};
複雑なメソッドの抽出については,ここではしばらく展開しない.
4.変換後のコードの実行
Test.javaを例に
js変換後のvar source="function Test(){};"
source += "Test.prototype.initv = function(){System.out.println(\"test\")}";
そしてdocument.write(source) 、
これでWindows[Test]でこのTestオブジェクトを入手し、彼の方法を実行することができます.
具体的なソースコードはClass._creatInitV()を参照できます.
また、重要なエントリ、Class.fornameメソッドをシミュレートする必要があります.このメソッドを実装することで、javaクラスの処理をうまく見つけることができます.
ソース:
ここでは、メンバーの処理方法とbeanオブジェクトのロード・アンロードの制御方法について、来週に引き続き説明します.
このようにコードを貼った文章を周到に書いていなければ、後でついてきます.http://ditu.alibaba.comあ、またどれだけのチェーンを稼ぐことができるか分かりません.
後で考えてみると、まだ実行可能で、実はjsでjvm仕様を実現するだけで、例えばjavaにとってSystem.out、println(「test」)があります.このような文が現れるとコンソールに「test」と出力されます.
この文法はjavascriptつまり
var System ={};
System.out={
println:function(val){
//具体的な機能を実現
alert(val);
}
}
Javaのjava.lang.Stringのように 上術方式を参照して実現することもでき、apiはこの方式で徐々に実現する.
それはjava beanオブジェクトをどのように変換するかについても今日お話しするポイントであり、java beanをjavascript objectに変換する方法ではapiが実現してもjava言語を実行させる環境はありません.
次に、変換方法について説明します.
まず簡単なjava beanとjavascript objectの違いを見てみましょう
public class Test{
private int a;
public int getA(){
reutrn a;
}
}
function Test{
}
Test.prototype.a = 0;
Test.prototype.getA = function(){
return this.a;
}
この2つの書き方を見ると、この方法への転換がはっきり見えるはずです.では、解析を始めます
解析プロセス:
1.クラス名の抽出
Java仕様によると、クラスの名前はclass name{...}でなければならないことがわかります.前に修飾子があり、内部クラスもそうです.
このような内容に正則的に一致するように書くことができます.最初に現れた{の文字列に一致し、classnameを抽出するだけです.
それとも正則(public|private|protected)?s*classs*w+?{ または class(.+?){ ルールに合致するすべてのデータをマッチングし、内部クラス名もマッチングします.
具体的なコードはClass.getName()を参照してください.
2.属性の抽出
正規の方法で処理することもできます.javaメンバー変数の特徴:修飾子(有無可能)+変数タイプ+メンバー名+";"(注意後にもう一つ;終了子)
ローカル変数との違いは戻り値タイプとmethodの違いは(){...}コードクリップがないことです
だから属性の抽出は正則を採用することができます
/(private|public)?\s+(void|int|float|boolean|double|String)[A-Za-z0-9|\s|_]+;
属性を処理する過程で、javaのintタイプのメンバー変数のデフォルト値が0などの変数タイプを処理する必要があります.
そこで,メンバ変数タイプに対応するvar Type={
"int":0,
"boolean":false
}
「public int a;」という文字列に一致したと仮定します.
そして私たちはこのように処理することができます
classname.prototype.a =Type[int];
3.メソッドの抽出(メイン関数mainメソッドの処理を先に紹介)
methodの抽出は比較的面倒な点であり,{}ラベル閉鎖の処理を考慮する必要がある.
mainメソッドもメインエントリ関数ですが、存在する場合は中身を実行します.public void static main(String[]args)……{....}でなければなりません.また、1つのクラスに1つしかありません.期間中argsはパラメータエントリで、argumentsに対応します.
対応するjsに変換すると
classname.prototype.ininv = function(){....};
複雑なメソッドの抽出については,ここではしばらく展開しない.
4.変換後のコードの実行
Test.javaを例に
public class Test{
public void static main(String[] args){
System.out.println("test");
}
}
js変換後のvar source="function Test(){};"
source += "Test.prototype.initv = function(){System.out.println(\"test\")}";
そして
これでWindows[Test]でこのTestオブジェクトを入手し、彼の方法を実行することができます.
具体的なソースコードはClass._creatInitV()を参照できます.
また、重要なエントリ、Class.fornameメソッドをシミュレートする必要があります.このメソッドを実装することで、javaクラスの処理をうまく見つけることができます.
ソース:
<script>
/*
* jtrim ,
* trim()
* trim("xyz") xyz
* trim(/[0-9]/g)
* trim(2) 2
* trim(0,3) 3
* trim(2,3) 2 3
*/
String.prototype.trim = function(){
var _argument = arguments[0] == undefined ? " " : arguments[0];
if(typeof(_argument) == "string"){
if (_argument == " ") {
return this.replace(/(^(\s|\u3000)*)|((\s|\u3000)*$)/g, "");
} else {
return this.replace(new RegExp("(^" + _argument + "*)|(" + _argument + "*$)", "g"), "");
}
}else if(typeof(_argument) == "object"){
return this.replace(_argument, "");
}else if(typeof(_argument) == "number"){
if (arguments.length == 1) {
return this.substring(arguments[0])
} else if(typeof(arguments[1]) == "number") {
return this.substring(arguments[0], this.length-arguments[1]);
}
}
return this;
};
// java system , js class
var System = {}
System.out ={
println:function(val){
this.print(val + "\r
");
},
print:function(val){
val = val == undefined ? "undefined" : val;
if(typeof(val) == "string"){
alert(val);
}
}
}
//js jvm , 4
var Type = {
"int" : 0,
"boolean" : false,
"float" : 0.0,
"double" : 0.0,
"String" : null,
"void" : null,
}
// java , java class.forname
var Class = {
source : "",
//
javasource : "",
forName:function(javasource){
this.javasource = javasource;// javasource,
var classname = this.getName();
this.source += "function "+classname+"(){}";// , js obj classname jsobj
//this.source += classname+"prototype."+
this.source += this._createInitV(classname);// main
this.source += this._createAttributes(classname);//
//this.getDeclaredFields();
this.source += this._createMethods(classname);//todo
return this;
},
// , public static void main
_createInitV:function(classname){
var str = "";
var initv = String.trim(this.javasource).match(/public static void main\(String\[\].+?\){(.+?)}/);
if(initv.length >= 1){
str += classname+".prototype.initv=function(){";
str += (initv.length == 2)? initv[1]:"";//init[1] main
str += "};";
}
return str;
},
//
//
//todo public void getXXX(){int xxx;} int xxx; , method attribute
//todo abstract
_createAttributes : function(classname){
var value = "";
var attrs = String.trim(this.javasource).match(/(private|public)?\s+(void|int|float|boolean|double|String)[A-Za-z0-9|\s|_]+;/g);
var attr="";
for(var i=0,length=attrs.length;i<length;i++){
attr = String.trim(attrs[i]);
if(attr != ""){
// public private protected, ;
if(attr.indexOf("public") == 0){
attr = attr.substring("public".length,attr.length-1).trim();
}else if(attr.indexOf("private") == 0){
attr = attr.substring("private".length,attr.length-1).trim();
}else if(attr.indexOf("protected")){
attr = attr.substring("protected".length,attr.length-1).trim();
}
// + 。。。
//
var typevalue = Type[attr.substring(0,attr.indexOf(" "))];// type value
var attrname = attr.substring(attr.indexOf(" ")).trim();// attribute name
// js
value += classname + ".prototype."+ attrname;
value += "=";
value += typevalue;
value += ";";
}
}
return value;
},
// method
//(private|public)?\s+(void|int|float|boolean|double|String)[A-Za-z0-9|\s]+\((void|int|float|boolean|double|String)?(.+)?\)\s+{\s+([\r|
|\t])?.+\s+([\r|
|\t])?}
// public ,private , _methodname
_createMethods : function(classname){
var value = "";
// public
var methods = String.trim(this.javasource).match(/(public)?\s+(void|int|float|boolean|double|String)[A-Za-z0-9|\s]+\((void|int|float|boolean|double|String)?(.+)?\)\s+{\s+([\r|
|\t])?.+\s+([\r|
|\t])?}/ig);
if(methods){
for(var i=0,length = methods.length;i<length;i++){
value = this.javaMethodTojsFunction(methods[i]);
}
}
// private
return "";
},
//java method js function
//public int getXXX(){} --> getXXX : function(){}
//todo ? public , java
_javaMethodTojsFunction : function(val){
if(val.indexOf("public") == 0){
val = val.substring("public".length).trim();// public,public js , public
}
val = val.substring(val.indexOf(" ")).trim();// type
var methodname = val.substring(0,val.indexOf("(")).trim();// ( , method ()
var functioncontent = val.substring(val.indexOf("(")).trim();// , function
functioncontent = "function"+ functioncontent;// function(){} (){} java , js
},
// return
_returnCompile : function(val){
},
getDeclaredFields:function(){
this.source += "Test.prototype = {";
this.source += "initv:function(){";
//initv --> , ,
//...
// system.out.println method -->alert
this.source += "alert(\"hello world\");";
this.source += "}";
this.source += "}";
},
//
getName:function(){
// class name { , 1 ,
// ,
var names = String.trim(this.javasource).match(/class(.+?){/g);
var name = names[0].substring("class".length,names[0].length-1);
return String.trim(name);
}
}
function JVM(){
}
JVM.prototype ={
compile:function(javasource){
var obj = new Object();
obj = Class.forName(javasource);
//obj = eval(obj.source);
///obj.initv();
document.write("<script>"+obj.source+"<\/script>");//todo package , namespaces
return window[obj.getName()]; //classname
}
}
var javasource = "public class Test { ";
javasource += "private int tmpa;";
javasource += "private boolean tmpb;";
javasource += "private float tmpc;";
javasource += "private double tmpd;";
javasource += "private String tmpe;";
javasource += "private Object tmpf;";
javasource += "public int getTmpa(){";
javasource += " return tmpa;";
javasource += "}";
javasource += "public static void main(String[] args){";
javasource += "System.out.println(\"hello world\");";
javasource += "System.out.println(\"world is round\");";
javasource += "}";
javasource += "class Test2 {";
javasource += "private int tmpz;";
javasource += "};"
javasource += "}";
// jsjvm
var jsjvm = new JVM();
// java
var obj = jsjvm.compile(javasource);
//
var tes = new obj();
// ,main init ,
tes.initv();
alert(tes.tmpb);
alert(tes.tmpe);
//alert(" 123".trim())
//(public)?\s*(void|int|float|boolean|double|String)[A-Za-z0-9|\s]+\((void|int|float|boolean|double|String)?(.+)?\)\s*{\s*([\r|
|\t])*.+\s*([\r|
|\t])?*}
</script>
ここでは、メンバーの処理方法とbeanオブジェクトのロード・アンロードの制御方法について、来週に引き続き説明します.
このようにコードを貼った文章を周到に書いていなければ、後でついてきます.http://ditu.alibaba.comあ、またどれだけのチェーンを稼ぐことができるか分かりません.
Google : email:[email protected] 2011.12.25