方法1:isInitializer()
/** An environment is an "initializer" if it is a constructor or
* an instance initializer.
*/
static boolean isInitializer(Env 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 env, TypeSymbol c) {
return isAccessible(env, c, false);
}
public boolean isAccessible(Env 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)
}
}
}