Java之内部类、匿名内部类、Lambda表达式和方法引用

简介: 1.内部类、2.匿名内部类、(重点掌握)3.Lambda表达式、4.方法引用


1.内部类

内部类顾名思义就是一个类里面再次定义一个类,这样做有好处也有坏处,好处是如果使用了内部类,那么这两个类之间的通信将会十分轻松。比如私有属性传递,但是缺点也很明显,就是内部类会导致类的结构复杂化。

内部类访问外部类私有化属性,方法的格式 与其实例化过程:

实例化过程

外部类.内部类  对象名称= new 外部类().内部类()

public class OuterClass {
    public class InnerClass {
        public void display() {
            System.out.println("This is the inner class.");
        }
    }
}
public class Example {
    public static void main(String[] args) {
        OuterClass.InnerClass obj = new OuterClass().new InnerClass();
        obj.display();
    }
}

image.gif

访问外部私有属性和方法等

str = 外部类.this.str

当实现static定义内部类时候,其访问外部类的属性方法的格式和实例化过程:

1.实例化过程

外部类.内部类 实例化对象名称 = new 外部类.内部类();

2.访问外部私有属性和方法

str = 外部类.str

public class OuterClass {
    private static int outerStaticField = 100;
    private int outerField = 200;
    public static class InnerClass {
        public void display() {
            System.out.println("Outer static field: " + outerStaticField);
        }
    }
    public static void outerStaticMethod() {
        System.out.println("Calling outer static method");
    }
}
public class Example {
    public static void main(String[] args) {
        OuterClass.InnerClass obj = new OuterClass.InnerClass();
        obj.display();
        OuterClass.outerStaticMethod();
    }
}

image.gif

注意:可以直接访问外部类的静态成员(包括静态属性和静态方法),但不能直接访问外部类的非静态成员(非静态属性和非静态方法)。

两者的区别:

1.当用static定义内部类时候,那么内部类其实就是一个独立的个体了所以可以不需要实例化其外部类就嗯呢更直接实例化内部类

除了内部类还可以有内部接口,接口内部实现抽象类,接口子类定义内部类

1.内部接口:

public class Example {
    interface InnerInterface {
        void display();
    }
    public static void main(String[] args) {
        InnerInterface innerObj = new InnerInterface() {
            public void display() {
                System.out.println("Inner interface implementation");
            }
        };
        innerObj.display();
    }
}

image.gif

2.接口内部实现抽象类

public interface OuterInterface {
    abstract class InnerAbstractClass {
        abstract void display();
    }
}
public class Example implements OuterInterface.InnerAbstractClass {
    public void display() {
        System.out.println("Implementation of inner abstract class");
    }
    public static void main(String[] args) {
        Example obj = new Example();
        obj.display();
    }
}

image.gif

3.接口子类定义内部类

interface OuterInterface {
    void outerMethod();
    class InnerClass {
        void innerMethod() {
            System.out.println("Inner class method");
        }
    }
}
class Example implements OuterInterface {
    public void outerMethod() {
        InnerClass innerObj = new InnerClass();
        innerObj.innerMethod();
    }
    public static void main(String[] args) {
        Example obj = new Example();
        obj.outerMethod();
    }
}

image.gif

4.方法种定义内部类

虽然一般内部类在类的哪里都可以进行定义,到那时,一般情况下,内部类都是定义在外部类的方法里面

public class OuterClass {
    public void outerMethod() {
        class InnerClass {
            void innerMethod() {
                System.out.println("Inner method");
            }
        }
        InnerClass innerObj = new InnerClass();
        innerObj.innerMethod();
    }
    public static void main(String[] args) {
        OuterClass obj = new OuterClass();
        obj.outerMethod();
    }
}

image.gif


2.匿名内部类

问题引出:由于一般情况下一个public类对应一个.java文件,那么如果类功能简单情况下,很多的类下就会产生大量的java类文件。所以通过匿名内部类可以不产生子类,就能完成子类带来的功能。

public class Main {
    public static void main(String[] args) {
        // 创建接口对象并调用方法
        MyInterface myInterface = new MyInterface() {
            @Override
            public void doSomething() {
                System.out.println("匿名内部类实现的方法");
            }
        };
        myInterface.doSomething(); // 输出:匿名内部类实现的方法
    }
}
// 定义接口
interface MyInterface {
    void doSomething();
}

image.gif


(重点掌握)3.Lambda表达式

匿名内部类由于其实现是比较复杂的,所以就诞生了Lambda表达式,这种表达式极大的简化的匿名内部类的操作

实现Lambda的语法有两种:

1.()->{方法体}

Runnable runnable = () -> {
    System.out.println("Hello, world!");
};

image.gif

2.()->语句

Calculator calculator = (a, b) -> a + b;

image.gif

@FunctionInterface注解

表示函数式接口,接口内只能出现一种抽象类方法

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);
}
public class LambdaExample {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        int result = add.calculate(10, 5);
        System.out.println("Addition result: " + result);
        Calculator subtract = (a, b) -> a - b;
        result = subtract.calculate(10, 5);
        System.out.println("Subtraction result: " + result);
    }
}

image.gif


4.方法引用

引用并不陌生,在以前的java的实例中就有着大量的引用,但是引用的大部分都是实例化对象,或者引用值,这里是对方法的引用。方法的引用分为三类:引用静态方法 引用某个对象的方法 引用特定类型的方法 引用构造方法

方法引用有以下四种:

引用静态方法 :                 类名称::static方法名称

@FunctionalInterface
interface Calculator {
public void caculate();
}
// 静态方法
class MathUtils {
    public static int multiply(int a, int b) {
        return a * b;
    }
}
// 方法引用
Calculator calculator = MathUtils::multiply;
int result = calculator.calculate(5, 3);
System.out.println("Multiplication result: " + result);

image.gif

引用某个对象的方法 :    实例化对象::普通方法

// 对象方法
class StringUtils {
    public int getLength(String str) {
        return str.length();
    }
}
// 方法引用
StringUtils stringUtils = new StringUtils();
Calculator calculator = stringUtils::getLength;
int result = calculator.calculate("Hello");
System.out.println("String length: " + result);

image.gif

引用特定类型的方法  :    特定类::普通方法

// 指定类型的方法
class StringUtils {
    public static boolean startsWith(String str, String prefix) {
        return str.startsWith(prefix);
    }
}
// 方法引用
BiPredicate<String, String> startsWith = StringUtils::startsWith;
boolean result = startsWith.test("Hello", "He");
System.out.println("Starts with 'He': " + result);

image.gif

引用构造方法:                   类名称::new

// 构造方法
class Person {
    private String name;
    public Person(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
// 方法引用
Function<String, Person> personFactory = Person::new;
Person person = personFactory.apply("John");
System.out.println("Person name: " + person.getName());

image.gif


目录
相关文章
|
17天前
|
Java API 开发者
Java中的Lambda表达式与Stream API的协同作用
在本文中,我们将探讨Java 8引入的Lambda表达式和Stream API如何改变我们处理集合和数组的方式。Lambda表达式提供了一种简洁的方法来表达代码块,而Stream API则允许我们对数据流进行高级操作,如过滤、映射和归约。通过结合使用这两种技术,我们可以以声明式的方式编写更简洁、更易于理解和维护的代码。本文将介绍Lambda表达式和Stream API的基本概念,并通过示例展示它们在实际项目中的应用。
|
19天前
|
Java API 开发者
Java中的Lambda表达式:简洁代码的利器####
本文探讨了Java中Lambda表达式的概念、用途及其在简化代码和提高开发效率方面的显著作用。通过具体实例,展示了Lambda表达式如何在Java 8及更高版本中替代传统的匿名内部类,使代码更加简洁易读。文章还简要介绍了Lambda表达式的语法和常见用法,帮助开发者更好地理解和应用这一强大的工具。 ####
|
19天前
|
Java 数据处理 数据安全/隐私保护
Java处理数据接口方法
Java处理数据接口方法
24 1
|
16天前
|
安全 Java API
Java中的Lambda表达式:简化代码的现代魔法
在Java 8的发布中,Lambda表达式的引入无疑是一场编程范式的革命。它不仅让代码变得更加简洁,还使得函数式编程在Java中成为可能。本文将深入探讨Lambda表达式如何改变我们编写和维护Java代码的方式,以及它是如何提升我们编码效率的。
|
19天前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
24 0
|
3天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
28 6
|
18天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
16天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
18天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
12天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####