javac的Resolve类解读

方法1:isInitializer()

/** An environment is an "initializer" if it is a constructor or
     *  an instance initializer.
     */
    static boolean isInitializer(Env<AttrContext> env) {
        Symbol owner = env.info.scope.owner;
        return owner.isConstructor() ||
                owner.owner.kind == TYP &&
                (owner.kind == VAR || owner.kind == MTH && (owner.flags() & BLOCK) != 0) &&
                (owner.flags() & STATIC) == 0;
    }

根据如上方法可以看出检查了如下三种情况的initializer:

public class TestInitializer {

	TestInitializer() { // constructor

	}

	int a = 2;   // instance variable initializer

	{  // instance initializer block
		a = 3;
	}
}

方法2:isAccessable()

/** Is class accessible in given environment?
     *  @param env    The current environment.
     *  @param c      The class whose accessibility is checked.
     */
    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c) {
        return isAccessible(env, c, false);
    }

    public boolean isAccessible(Env<AttrContext> env, TypeSymbol c, boolean checkInner) {
        boolean isAccessible = false;
        switch ((short)(c.flags() & AccessFlags)) {
            case PRIVATE:
                isAccessible =
                    env.enclClass.sym.outermostClass() ==
                    c.owner.outermostClass();
                break;
            case 0:
                isAccessible =
                    env.toplevel.packge == c.owner // fast special case
                    ||
                    env.toplevel.packge == c.packge()
                    ||
                    // Hack: this case is added since synthesized default constructors
                    // of anonymous classes should be allowed to access
                    // classes which would be inaccessible otherwise.
                    env.enclMethod != null &&
                    (env.enclMethod.mods.flags & ANONCONSTR) != 0; // anonconstr 匿名构造函数
                break;
            default: // error recovery
            case PUBLIC:
                isAccessible = true;
                break;
            case PROTECTED:
                isAccessible =
                    env.toplevel.packge == c.owner // fast special case
                    ||
                    env.toplevel.packge == c.packge()
                    ||
                    isInnerSubClass(env.enclClass.sym, c.owner);
                break;
        }
        return (checkInner == false || c.type.getEnclosingType() == Type.noType) ?
            isAccessible :
            isAccessible && isAccessible(env, c.type.getEnclosingType(), checkInner);
    }  

检查的是TypeSymbol是否在某个Env中被访问到,能否访问到最终还要看Java的权限控制符public、protected、default和private。

另外需要知道的是只有Inner Class才可以为protected和private进行修饰。重点看一下protected修饰的类的逻辑。

public class Test {

	protected class D {
		public D() {
			// TODO Auto-generated constructor stub
		}
	}
}

  

class A { // only public, abstract & final are permitted
	// protected class D{}
}

public class TestAccessible {

	protected class B { // public,protected,private are permitted

	}

	public void method() {
		new A();  // 走env.toplevel.packge == c.owner
		new B();  // 走env.toplevel.packge == c.packge
	}

	class C extends Test{
		public void method3(){
			new D(); // 走isInnerSubClass(env.enclClass.sym,c.owner)
		}
	}

}

  

  

时间: 2024-12-27 21:55:51

javac的Resolve类解读的相关文章

Java类文件结构及javac的ClassReader类解读

首先来看一下ClassFile,类注释如下: A JVM class file. Generic Java classfiles have one additional attribute for classes, methods and fields: "Signature" (u4 attr-length, u2 signature-index) A signature gives the full Java type of a method or field. When used

用javac编译servlet类出现问题

本人写了一个关于servlet的webapp,但是在用javac编译的时候,只是单纯的将jsp-api.jar和servlet-api.jar拷贝放在了其目录下面,然后利用命令行 javac XXX.java开始编译,然后出现了一大堆错误,如下: FirstServlet.java:7: 错误: 找不到符号public class FirstServlet extends HttpServlet ^ 符号: 类 HttpServletFirstServlet.java:9: 错误: 找不到符号

C#封装CRUD到SqlHelper类解读

1.简单说明一下,一般情况下,数据库连接字符串是在App.config文件中进行配置,然后再在代码中进行引用.因此,我们在这里先看一下App.config文件. 首先看需要添加的内容: 参数说明: name:表示键值,在代码中需要通过这键值来找到对应的连接字符串信息. connectionString:链接数据库的字符串信息.Server:数据库服务器,Database:数据库,uid:数据库账户名,pwd:数据库密码 <?xml version="1.0" encoding=&

Javac内部类本地类

One way declared types in Java differ from one another is whether the type is a class (which includes enums) or an interface (which includes annotation types). An independent property of a type is its relation to the surrounding lexical context. A to

javac编译原理

java源代码(符合语言规范)-->javac-->.class(二进制文件)-->jvm-->机器语言(不同平台不同种类) 如何让java的语法规则适应java虚拟机的语法规则?这个任务由javac编译器来完成java语言规范转换成java虚拟机语言规范. 编译流程: 流程: 词法分析器:将源码转换为Token流 将源代码划分成一个个Token(找出java语言中的if,else,for等关键字) 语法分析器:将Token流转化为语法树 将上述的一个个Token组成一句句话(或者

javac 编译器原理

Javac 是什么 javac 是一种编译器,能讲一种语言规范转化成另外一种语言规范.如C,C++都是将源码直接编译成目标机器码,这个目标机器码是CPU直接执行的指令集合. 这些指令集合也就是底层的一种语言规范,机器能够直接识别这种语言规范,但是人不可能直接去写目标机器码. 从某种意义来说,有了编译器才有了程序语言的繁荣,因为编译器是人类和机器沟通的一个纽带.javac 的编译器也是将JAVA 这种对人非常友好的编程语言编译成对所有机器都非常友好的语言. javac 的任务就是将Java源码编译

javac编译过程

编译器把一种语言规范转化为另一种语言规范的这个过程需要哪些步骤: (1) 词法分析:读取源代码,一个字节一个字节的读进来,找出这些词法中哪些是我们定义的语言关键词如:if  else where 等 识别哪些if是合法的哪些是不合法的. 词法分析的结果:就是从源代码中找出一些规范化的token流,就像人类语言中,给你一句话你要分辨出哪些是一个词语,哪些是标点符号,哪些是动词,哪些是名词. (2) 语法分析:就是在词法分析中得到的token流进行语言分析,这一步就是检查这些关键词组合在一起是不是符

Google-Guava-EventBus源码解读

Guava是Google开源的一个Java基础类库,它在Google内部被广泛使用.Guava提供了很多功能模块比如:集合.并发库.缓存等,EventBus是其中的一个module,本篇结合EventBus源码来谈谈它的设计与实现. 概要 首先,我们先来预览一下EventBus模块的全部类图: 类并不是多而且几乎没有太多继承关系. 下面,我们来看一下各个类的职责: EventBus:核心类,代表了一个事件总线.Publish事件也由它发起. AsyncEventBus:在分发事件的时候,将其压入

Javac源码简单分析之Javac简单介绍

一.简单介绍 javac 是java语言编程编译器.javac工具读由java语言编写的类和接口的定义,并将它们编译成字节代码的class文件. 二.源码获取 OpenJDK6源码:http://download.java.net/openjdk/jdk6/ Javac的源码就在OpenJDK源码里面. 或者在CSDN下载:http://download.csdn.net/detail/p_3er/7383741 三.Javac的包 Javac的公共入口点是com.sun.tools.javac