方法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