Java8メソッド参照と匿名内部クラス

Java 8メソッドリファレンスの概要と例を参照してください:https//www.cnblogs.com/xingzc/p/6002873.html

Javaの.classバイトコードファイルでは、メソッド参照はinvoke-dynamic命令を介して実装されます。この命令は、javap -cxxx.classを介してコードを逆アセンブルすることで表示できます。
ただし、Androidの.dex / .smaliバイトコードファイルでは、ART / Davilk仮想マシンがinvoke-dynamicと同様の命令を実装していないためです(https://source.android.google.cn/devices/tech/ dalvik / dalvik-を参照)。バイトコード)、したがって、Androidコンパイラは、.classバイトコードを.smaliバイトコードに変換するプロセスで、メソッドによって参照されるinvoke-dynamic命令を同等の匿名内部クラスコード命令に変換します。

次のコードの同等のコードは、メソッドによって参照されるAndroidAPKのコードを逆コンパイルすることによって取得されます。
(Android Studioでコードを記述し、apkをコンパイルしてから、apktoolを使用してapkを逆コンパイルしてsmaliコードを取得し、最後にsmaliコードを使用してJavaコードを起動解除します)

class Car {
    public static void say(Car car) {
        System.out.println("This is " + car);
    }

    public void run() {
        System.out.println(this + " running");
    }

    public void follow(Car another) {
        System.out.println(this + " following " + another);
    }
}

public class SupplierTest {
    
    
    public static Car create(Supplier<Car> supplier) {
        return supplier.get();
    }

    public static Car testCreate() {
        Car ret = create(Car::new); // 构造器引用,语法是Class::new,或者更一般的形式:Class<T>::new。注意:这个构造器没有参数。
        ret = create(Lambda$0.$instance); // 等效代码 Equivalent code

        return ret;
    }

    public static void main(String[] args) {
        final Car car = testCreate();
        final List<Car> cars = Arrays.asList(car);

        cars.forEach(Car::say); // 静态方法引用,语法是Class::static_method。注意:这个方法接受一个Car类型的参数。
        cars.forEach(Lambda$1.$instance); // 等效代码 Equivalent code

        cars.forEach(Car::run); // 成员方法的引用,语法是Class::method。注意,这个方法没有定义入参。
        cars.forEach(Lambda$2.$instance); // 等效代码 Equivalent code

        final Car police = testCreate();
        System.out.println(police + " is a police car");

        cars.forEach(police::follow); // 某个实例对象的成员方法的引用,语法是instance::method。注意:这个方法接受一个Car类型的参数。
        cars.forEach(Lambda$3.get$Lambda(police)); // 等效代码 Equivalent code
    }

    // for Car::new
    static final class Lambda$0 implements Supplier<Car> {
        static final Supplier<Car> $instance = new Lambda$0();

        @Override
        public Car get() {
            return new Car();
        }
    }

    // for Car::say (static method)
    static final class Lambda$1 implements Consumer<Car> {
        static final Consumer<Car> $instance = new Lambda$1();

        @Override
        public void accept(Car car) {
            Car.say(car);
        }
    }

    // for Car::run (non-static method)
    static final class Lambda$2 implements Consumer<Car> {
        static final Consumer<Car> $instance = new Lambda$2();

        @Override
        public void accept(Car car) {
            car.run();
        }
    }

    // for police::follow
    static final class Lambda$3 implements Consumer<Car> {
        private final Car arg$1;

        private Lambda$3(Car police) {
            arg$1 = police;
        }

        static Consumer<Car> get$Lambda(Car police) {
            return new Lambda$3(police);
        }

        @Override
        public void accept(Car car) {
            arg$1.follow(car);
        }
    }
}

おすすめ

転載: blog.csdn.net/hegan2010/article/details/79243561