[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の違いを見てみましょう
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\")}";
そしてdocument.write(source)
これで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