Nester
Nester is a tool to patch inner class attributes in Java class files. It takes in a Nests data file and applies those patches to a jar file.
Inner Classes
Inner classes are classes that are defined inside other classes or methods. There are three types of inner classes: nested classes, local classes, and anonymous classes. Each type has its own uses, and a different relationship with its outer class or method.
Nested Classes
A nested class is a class declared inside another class.
public class Outer { ... public class Inner { ... } }
Nested classes can be static or non-static.
- A static nested class can access static members of its outer class, and vice versa, even if those members are private.
- A non-static nested class can access both static members and instance members of its outer class, and vice versa, even if those members are private.
Local Classes
A local class a class declared inside a method.
public class Outer { .... public void outer() { ... class Inner { ... } } }
A local class can access both static and instance members from its outer class, as well as local variables from the scope in which it is declared in its outer method.
Anonymous Classes
An anonymous class is a class declared and instantiated at the same time.
public class Outer { ... public void outer() { ... Runnable task = new Runnable() { ... } } }
An anonymous class can access both static and instance members from its outer class, as well as local variables from the scope in which it is declared in its outer method.
Special Classes
The Java compiler may generate special classes for some of the language features. These synthetic classes are normally invisible.
- Switch statements are compiled to classes with enum value tables.
- A completely empty class may be generated and passed between multiple nested class and their outer class to enforce the contract for access between them.
Inner Class Attributes
Inner class attributes describe the relationship between inner classes and their outer classes or methods. Obfuscators such as ProGuard may remove them to shrink the jar file size. This is generally not a problem, since these attributes do not affect the runtime behavior of a Java application. However, they do make a difference at compile time.
Interactions with inner classes will not work properly if the inner class attributes are missing. Access between non-static nested classes and their outer classes will be broken, anonymous classes will be accessible when they should not be, and references to nested classes will not work.
On top of the compile time issues, decompiler results will be significantly worse for jars where the inner class attributes are not present. Local and anonymous classes will not appear inside their outer classes and methods, and member access between nested classes and their outer classes may appear as references to methods that do not exist.
The InnerClasses Attribute
The InnerClasses
attribute of a class contains entries for all inner classes referenced by that class. Each entry has four values:
inner class name
: the internal name of the inner classouter class name
: the internal name of the outer classinner name
: the simple name of the inner class (i.e. the name as declared in the source)inner class access
: the access modifier flags of the inner class
The outer class name
is empty for anonymous and local classes.
The inner name
value is empty for anonymous classes.
The EnclosingMethod Attribute
The EnclosingMethod
attribute of a class describes the outer class and method of an inner class. It has three values:
enclosing class name
: the internal name of the enclosing classenclosing method name
: the name of the enclosing methodenclosing method descriptor
: the type descriptor of the enclosing method
This attribute is only present for local and anonymous classes.
The enclosing method name
and enclosing method descriptor
values are empty for anonymous classes that are declared in in-line initializers for fields.