日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于符号Symbol第一篇

發布時間:2023/12/16 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于符号Symbol第一篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

Symbol類的一個實例代表一個符號。對于語法樹來說,并不是每個節點都有一個符號實例。下面列舉了哪些語法樹節點具有符號的引用,如下表格:

其中JCNewClass、JCAssignOp、JCUnary、JCBinary、JCFieldAccess與JCIdent繼承了JCExpression,可出現在表達式中。

?

如上的PackageSymbol、ClassSymbol、MethodSymbol、VarSymbol與TypeSymbol這些符號由用戶指定,而剩下的一些都是對既有符號的引用。如語法節點JCAssignOp中的operator。

下面來舉個具體的例子說明一下。

package m20170208;public class A<T> {public void test1() {int a = 3;int b = a + 2;}public void test2() {A ins = new A();ins.test1();} }

查看JCCompilationUnit語法節點的packge屬性,如下:

查看JCClassDecl語法節點,如下:

?查看JCTypeParameter節點。這個節點沒有直接對Symbol進行引用,而是通過type屬性的tsym來引用的,如下:

查看JCMethodDecl節點的sym屬性,如下:

?

?查看JCVariableDecl節點的sym屬性,如下:

?

??查看JCBinary節點的operator屬性,如下:

?

? 查看JCIdent節點的sym屬性,如下:  

? 查看JCNewClass節點的constructor屬性,如下:

? 查看JCFieldAccess節點的sym屬性,如下:

?

下面來介紹一下Symbol中一些重要的屬性。

屬性1:kind

** The kind of this symbol.* @see Kinds* * Java語言符號的種類,有包的符號、類型的符號、變量的符號、值的符號和方法的符號*/public int kind;

kind值取的是類Kinds中定義的一些常量,如下:

/** The empty set of kinds.*/public final static int NIL = 0; // 0/** The kind of package symbols.*/public final static int PCK = 1 << 0; // 1/** The kind of type symbols (classes, interfaces and type variables).*/public final static int TYP = 1 << 1; // 2/** The kind of variable symbols.*/public final static int VAR = 1 << 2; // 4 變量符號/** The kind of values (variables or non-variable expressions), includes VAR.** 在標記階段使用*/public final static int VAL = (1 << 3) | VAR; // 12 值(包括變量和非變量表達式),也包括變量/** The kind of methods.*/public final static int MTH = 1 << 4; // 16 方法/** The error kind, which includes all other kinds.包含所有其它類型的錯誤*/public final static int ERR = (1 << 5) - 1; // 31 包括剩下的其它種類

VAL一般是表達式的右端,例如:a = Exp;那么Exp可以是變量也可以是一個值,但是a絕對是一個變量。

OperatorSymbol的kind屬性值為16,也就是方法。因為這些符號最終的意思是通過方法來體現的,如int a = b+c;假如b與c是int類型變量,那么調用了有兩個int類型

參數的方法,將b與c傳入后,返回的結果即是a想要的結果。

?

對比Symbol例子的截圖查看kind的值。其中的NIL常量是在創建默認的noSymbol時使用過。在SymbolTable中的定義如下:

/** A symbol that stands for a missing symbol. */ public final TypeSymbol noSymbol;?

?

屬性2:flags_field

/** The flags of this symbol.* * 符號的標志*/public long flags_field; // 值來自Flags類中

Flags中有許多修飾符,如public、abstract等等,表示這個符號上有哪些修飾符。不過樹節點中使用的修飾符與這里的flags_field未必是一個值,例如定義在接口中的變量,編譯器默認會添加public、static、final修飾符,在記錄符號時,這個flags_field也會將這些修飾符在long值中對應的位置為1。

?

屬性3:attributes_field

/** The attributes of this symbol.* * 符號的屬性*/public List<Attribute.Compound> attributes_field;

舉個例子,如下:

import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Target(ElementType.PACKAGE) @Retention(RetentionPolicy.RUNTIME) @interface MzTargetPackage {public String version() default ""; }

定義一個包注解

@MzTargetPackage(version="1.0") package m20170208;

在包上使用包注解,查看attributes_field屬性的值,如下:

  

  

?

屬性4:name

/** The name of this symbol in Utf8 representation.* 符號的名稱*/public Name name;

這個name就是NameImpl對象,在前面也講解過。

屬性5:type

/** The type of this symbol.* * 符號的類型*/public Type type;

有許多具體的Type類。

  

屬性6:owner

/** The owner of this symbol.*/public Symbol owner;

從Symbol例子的各個截圖中可以查看到各個owner的具體值。其中OperatorSymbol由于是預定義好的,所以其owner歸屬于預定義的ClassSymbol中。  

舉個例子,如下:?

class Test{Test o = new Test(){},x = o; }

x這個VarSymbol還是屬性ClassSymbol(Test),在詞法分析階段就是兩個獨立變量的聲明,變為了如下形式:

class Test{Test o = new Test(){};Test x = o; }

?new Test(){}為JCNewClass,而del屬性為JCClassDecl,如下截圖。

其中的匿名類的owner為VarSymbol,如下:

?

屬性6:erasure_field

/** A cache for the type erasure of this symbol.*/public Type erasure_field;

表示泛型擦除后的類型,如類A的泛型擦除后,其值如下:

  

?又如JCNewClass中的MethodSymbol(A())中的此屬性值,如下:

創建類對象的實例時,其實是調用的這個類的構造函數(被當作特殊的方法來對待)。、?

?

方法1:public boolean isInheritedIn(Symbol clazz, Types types)

/** Is this symbol inherited into a given class?* PRE: If symbol's owner is a interface,* it is already assumed that the interface is a superinterface of given class.* @param clazz The class for which we want to establish membership.* This must be a subclass of the member's owner.*/ public boolean isInheritedIn(Symbol clazz, Types types) {switch ((int)(flags_field & Flags.AccessFlags)) { // AccessFlags中的值只能取其一default: // error recoverycase PUBLIC:return true;case PRIVATE:return this.owner == clazz;case PROTECTED:// we model interfaces as extending Object// 非接口時為true,接口時為false,因為接口里沒有public membersreturn (clazz.flags() & INTERFACE) == 0;case 0: // default訪問權限為同包或者同類,子類或者其它包是不可以訪問的PackageSymbol thisPackage = this.packge();for (Symbol sup = clazz;sup != null && sup != this.owner;sup = types.supertype(sup.type).tsym){while (sup.type.tag == TYPEVAR14) {sup = sup.type.getUpperBound().tsym;}if (sup.type.isErroneous()) {return true; // error recovery}if ((sup.flags() & COMPOUND) != 0) {/*eg1:interface IA{}interface IB{}class CA{}public class TestMethod{public <T extends CA&IA&IB>void methodA(){ }}*/continue;}if (sup.packge() != thisPackage) { // 當修飾符為默認時,則不同的包就造成了錯誤return false;}}// 非接口時為true,接口時為false,因為接口里沒有default membersreturn (clazz.flags() & INTERFACE) == 0;} }

如上的代碼在檢查某個symbol是否在繼承于某個Symbl,例如:

class AA{void test(){} }public class Outer<T extends AA> {class Inner<D extends T>{D d;public void x(){d.test();}} }  

要檢查d.test()中的MethodSymbol時就需要判斷是否由d這個TypeSymbol繼承而來的MethodSymbol。test()方法定義在AA類中,并且修飾符為default,走case 0分支。

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

  

  

?

轉載于:https://www.cnblogs.com/extjs4/p/6382477.html

總結

以上是生活随笔為你收集整理的关于符号Symbol第一篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。