#2903·jadx

[core] nested class emitted without 'static' when the InnerClass STATIC flag is stripped

Author: obus-globusCreated Jul 1, 2026Updated Jul 1, 2026

Issue details

jadx takes a nested class's static modifier straight from the InnerClass attribute and never re-infers it. R8 can strip the STATIC flag from a class that is in fact static (its constructor takes no synthetic outer-this argument). The class is then emitted non-static, so a new Outer.Inner() from a static context does not compile.

The information to recover it is already in the bytecode: a non-static inner class's constructor has a synthetic first argument of the outer type (this is exactly the check in MethodNode.java#L535-L540). A member class whose constructors have no such argument is static. The subtlety is that this must apply only to member classes: local and anonymous classes also lack the outer-this arg but cannot be static. A naive add-only inference over any inner class with no outer-this ctor wrongly marks a non-inlined $1-style or local class static (it regresses TestIncorrectAnonymousClass), and there is no enclosing-method info to separate member classes from those, so this needs a signal beyond the class name.

Sample

Outer.smali (member class a with a static factory):

.class public La;
.super Ljava/lang/Object;

.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        La$b;
    }
.end annotation

.method public static make()La$b;
    .registers 1
    new-instance v0, La$b;
    invoke-direct {v0}, La$b;-><init>()V
    return-object v0
.end method

Inner.smali (static in fact -- no outer-this ctor arg -- but the InnerClass STATIC flag is absent):

.class public La$b;
.super Ljava/lang/Object;

.annotation system Ldalvik/annotation/EnclosingClass;
    value = La;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x1
    name = "b"
.end annotation

.method public constructor <init>()V
    .registers 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    return-void
.end method

Output on master (8c28a85), does not compile (new a.b() in a static method needs an enclosing a instance):

public class a {
    public class b {
    }

    public static a.b make() {
        return new a.b();
    }
}

Jadx version

master 8c28a85 (current HEAD)