DEV Community

Liu yu
Liu yu

Posted on

非静态内部类问题及Lambda 表达式


package com.process;

public class Lambda {

    interface Ilike{
        void lambda();
    }
    class Like implements Ilike {
        @Override
        public void lambda() {
            System.out.println("I like lambda");
        }
    }

    public static void main(String[] args) {
        Ilike like=new Like();
        like.lambda();
    }
}


Enter fullscreen mode Exit fullscreen mode

我照着狂神的代码写了,发现报错

无法从静态上下文中引用非静态 变量 this
Enter fullscreen mode Exit fullscreen mode

Deepseek告诉我

在静态方法中直接创建非静态内部类实例时,需要先有外部类实例(否则无法访问隐含的 this 引用)
Enter fullscreen mode Exit fullscreen mode

"在静态方法中直接创建非静态内部类实例时,需要先有外部类实例(否则无法访问隐含的 this 引用)" 这句话就是最核心的问题所在。

核心概念分解

  1. 非静态内部类(Like类)

    • 它"寄生"在外部类(Lambda类)里
    • 每个非静态内部类实例必须绑定一个外部类实例
    • 内部类实例会自动获得一个隐形的this引用,指向它所属的外部类对象
  2. 静态方法(main方法)

    • 没有"主人对象"(没有this
    • 是独立存在的,不依附于任何对象
  3. 错误原因

   new Like(); // 在静态方法中这样写
Enter fullscreen mode Exit fullscreen mode

实际相当于:

   this.new Like(); // 但静态方法中没有this!
Enter fullscreen mode Exit fullscreen mode
  • Java要求创建非静态内部类时必须提供外部类的this引用
  • 但静态方法里根本没有this对象!

生活比喻

想象你在造一辆汽车:

  • 外部类 = 汽车框架
  • 非静态内部类 = 发动机
  • 静态方法 = 汽车设计图纸

错误做法:

你看着设计图纸(静态方法)说:"我要造个发动机!"

但问题:你连汽车框架(外部类实例)都还没造出来!

发动机根本无处安装!

正确做法:

  1. 先造出汽车框架(new Lambda()
  2. 再把发动机装到框架上(outer.new Like()

解决方案图解

静态方法(main)
│
├ 错误路径:直接 new Like() 
│   → 失败!没有外部类实例
│
└ 正确路径:
   1. new Lambda()   → 创建外部类实例(造车架)
   2. outer.new Like() → 创建内部类(装发动机)
Enter fullscreen mode Exit fullscreen mode

关键记忆点

记住这个硬性规则

// 在静态方法中创建非静态内部类
外部类名 外部变量 = new 外部类名();  // 先造"房子"
内部类名 内部变量 = 外部变量.new 内部类名(); // 再在"房子"里造"房间"
Enter fullscreen mode Exit fullscreen mode

代码只需要修改一行:

public static void main(String[] args) {
    Lambda outer = new Lambda();  // 添加这行:先创建外部类实例
    Ilike like = outer.new Like(); // 修改这行:通过外部实例创建内部类
    like.lambda();
}
Enter fullscreen mode Exit fullscreen mode

如果把非静态内部类放在外面就可以了

package com.process;


interface Ilike{
    void lambda();
}
class Like implements Ilike {
    @Override
    public void lambda() {
        System.out.println("I like lambda");
    }
}
public class Lambda {


    public static void main(String[] args) {
        Ilike like=new Like();
        like.lambda();
    }
}

Enter fullscreen mode Exit fullscreen mode

关键区别

// 原代码 (错误)
public class Lambda {
    class Like { ... } // 内部类 (非静态)
}

// 新代码 (正确)
public class Lambda { ... } // 主类
class Like { ... }          // 独立的普通类
Enter fullscreen mode Exit fullscreen mode

为什么正确了?

  1. Like不再是内部类

    • 现在Like是一个顶级类(top-level class)
    • 它不再依附于Lambda
    • 就像两个独立的公民,没有从属关系
  2. 创建对象不需要外部实例

   new Like(); // 直接创建,不需要任何外部对象
Enter fullscreen mode Exit fullscreen mode
  • 因为Like现在是普通类,不依赖其他类
  • 在静态方法中可以直接实例化
  1. 类关系变化
   原结构:
   Lambda (房子)
   └── Like (房间,需要房子才能存在)

   新结构:
   Lambda (独立房子)
   Like   (另一个独立房子)
Enter fullscreen mode Exit fullscreen mode

核心知识点

内部类 vs 普通类

   | 特性         | 非静态内部类                  | 普通类 (顶级类)             |
   |--------------|-----------------------------|---------------------------|
   | 创建方式      | 需要外部类实例 `outer.new Inner()` | 直接 `new ClassName()`    |
   | 隐含引用      | 有指向外部类的 `this`          | 无                        |
   | 静态方法访问  | 必须先创建外部实例              | 可直接访问                |
Enter fullscreen mode Exit fullscreen mode

好,现在来学更高级的东西,可以有以下的写法

package com.process;


interface Ilike{
        void lambda();
    }

interface Love
{
    void fun(int a);
}

// 1.普通类
class Like1 implements Ilike {
    @Override
    public void lambda() {
        System.out.println("I like lambda1");
    }
}

public class Lambda {

    //2.静态内部类
    static class Like2 implements Ilike {
        @Override
        public void lambda() {
            System.out.println("I like lambda2");
        }
    }


    public static void main(String[] args) {
        Ilike like=new Like1();
        like.lambda();

        like=new Like2();
        like.lambda();

        //3.局部内部类
        class Like3 implements Ilike {
            @Override
            public void lambda() {
                System.out.println("I like lambda3");
            }
        }
        like=new Like3();
        like.lambda();


        //4.匿名内部类
        like=new Ilike() {
            @Override
            public void lambda() {
                System.out.println("I like lambda4"); 
            }
        };
        like.lambda();


        //5.使用Lambda表达式
        like = () -> System.out.println("I like lambda5");
        like.lambda();


        //6.使用Lambda表达式,变种
        //Love love = (int a) -> System.out.println("I like lambda"+a);
        //love.fun(6);

        //7.使用Lambda表达式,变种
        Love love = a -> {System.out.println("I like lambda"+a);};
        love.fun(6);
    } 
}


Enter fullscreen mode Exit fullscreen mode

Top comments (0)