首页 > 编程语言 >JAVA 内部类与Lambda

JAVA 内部类与Lambda

时间:2024-09-02 21:06:13浏览次数:8  
标签:JAVA 内部 void System class println public Lambda

JAVA 内部类与Lambda

目录

1 内部类

1.1 内部类基础

  • Java 一个类中可以嵌套另外一个类。举例:在一个类A的内部定义一个类B,类B就被称为内部类。语法格式如下:

    class OuterClass {   // 外部类
        // ...
        class NestedClass { // 嵌套类,或称为内部类
            // ...
        }
    }
    
  • 内部类访问特点

    • 内部类可以直接访问外部类的成员,包括私有

    • 由于内部类嵌套在外部类中,因此必须首先实例化外部类,然后创建内部类的对象来实现。

  • 嵌套类有两种类型

    • 内部类

    • 静态内部类

  • 成员内部类的定义位置

    • 在类中方法,跟成员变量是一个位置
  • 外界创建成员内部类格式

    格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
    举例:InnerClass.Inner ic = new InnerClass().new Inner();
    
  • 示例

    package com.fcarey.innerclass;
    
    public class InnerClass {
        int i = 0;
        private int j = 1;
    
        public class Inner {
            int k = 2;
    
            public void print() {
                System.out.println("public class Inner: " + i);
                System.out.println("public class Inner: " + j);
                System.out.println("public class Inner: " + k);
            }
        }
    }
    
    package com.fcarey.innerclass;
    
    public class Demo {
        public static void main(String[] args) {
            InnerClass.Inner ic = new InnerClass().new Inner();
            ic.print();
        }
    }
    

1.2 私有成员内部类

  • 内部类可以使用 private 或 protected 来修饰,如果你不希望内部类被外部类访问可以使用 private 修饰符:

    package com.fcarey.innerclass;
    
    public class InnerClass {
        int i = 0;
        private int j = 1;
    
        private class PrivateInner {
            public void print() {
                System.out.println("private class PrivateInner: " + i);
                System.out.println("private class PrivateInner: " + j);
            }
        }
    
        public void show() {
            PrivateInner privateInner = new PrivateInner();
            privateInner.print();
        }
    }
    
    package com.fcarey.innerclass;
    
    public class Demo {
        public static void main(String[] args) {
            InnerClass pic = new InnerClass();
            System.out.println(pic.i);
            // System.out.println(ic2.j); 报错,私有成员变量,外界无法使用,需要在方法内部创建对象并引用
            // System.out.println(ic2.k); 报错,局部内部变量,外界无法使用,需要在方法内部创建对象并引用
            pic.show();
        }
    }
    
    

1.3 静态内部类

  • 静态内部类可以使用 static 关键字定义,静态内部类我们不需要创建外部类来访问,可以直接访问它:

  • 静态成员内部类格式

    静态成员内部类访问格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
    
    静态成员内部类中的静态方法:外部类名.内部类名.方法名();
    
  • 示例

    package com.fcarey.innerclass;
    
    public class InnerClass {
        int i = 0;
        private int j = 1;
    
        static class PSInner {
            public void print() {
                System.out.println("private static class PrivateInner: print()");
            }
    
            public static void show() {
                System.out.println("private static class PrivateInner: show()");
            }
        }
    }
    
    package com.fcarey.innerclass;
    
    public class Demo {
        public static void main(String[] args) {
            InnerClass.PSInner psInner = new InnerClass.PSInner();
            psInner.print();
            InnerClass.PSInner.show();
        }
    }
    
    

1.4 局部内部类

  • 局部内部类定义位置

    • 局部内部类是在方法中定义的类
  • 局部内部类方式方式

    • 局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
    • 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
    • 注意:静态内部类无法访问外部类的成员。
  • 示例:

    package com.fcarey.innerclass;
    
    public class InnerClass {
        int i = 0;
        private int j = 1;
    
        public class Inner {
            int k = 2;
    
            public void print() {
                System.out.println("public class Inner: " + i);
                System.out.println("public class Inner: " + j);
                System.out.println("public class Inner: " + k);
            }
        }
        
        public void partShow() {
            int l = 3;
            class PartInner {
                int m = 4;
    
                public void print() {
                    System.out.println("class PartInner:" + i);
                    System.out.println("class PartInner:" + j);
    //                System.out.println("class PartInner:" + k);
                    System.out.println("class PartInner:" + l);
                    System.out.println("class PartInner:" + m);
                }
            }
            PartInner partInner = new PartInner();
            partInner.print();
        }
    }
    
    package com.fcarey.innerclass;
    
    public class Demo {
        public static void main(String[] args) {
            InnerClass partIC = new InnerClass();
            partIC.partShow();
        }
    }
    

1.5 匿名内部类

  • 匿名内部类的前提

    • 存在一个类或者接口,这里的类可以是具体类也可以是抽象类
  • 匿名内部类的格式

    格式:new 类名 ( ) {  重写方法 }    new  接口名 ( ) { 重写方法 }
    
  • 匿名内部类的本质

    • 本质:是一个继承了该类或者实现了该接口的子类匿名对象
  • 示例

    package com.fcarey.innerclass;
    
    /*
        接口
     */
    interface Inter {
        void show();
    }
    
    public class AnonymousClass {
        public static void main(String[] args) {
            new Inter() {
                @Override
                public void show() {
                    System.out.println("the function of Anonymous Class :匿名内部类");
                }
            }.show(); // 直接调用方法
    
            anonymousShow(new Inter() {
                @Override
                public void show() {
                    System.out.println("the function of Anonymous Class ");
                }
            });
    
            anonymousShow(() -> {
                System.out.println("the function of Anonymous Class ");
            });
        }
        /**
         * 使用接口的方法
         */
        public static void anonymousShow(Inter inter) {
            inter.show();
        }
    }
    

2 Lambda表达式

Lambda表达式体现了函数式编程思想:

  • 在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿数据做操作”

  • 面向对象思想强调“必须通过对象的形式来做事情”

  • 函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”

  • 组成Lambda表达式的三要素:形式参数,箭头,代码块

  • 格式:

    (形式参数) -> {代码块}
    
    // 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
    // ->:由英文中画线和大于符号组成,固定写法。代表指向动作
    // 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容
    

2.1 初识Lambda

2.1.1 无参无返回值抽象方法

package com.fcarey.innerclass;

public class LambdaTest {
    public static void main(String[] args) {
        
        // 通过匿名内部类实现
        useStringHander(new StringHandler() {
            @Override
            public void printMessage(String msg) {
                System.out.println(msg);
            }
        });
		// 通过Lambda表达式实现,其对匿名内部类做了优化
        useStringHander((msg -> {
            System.out.println("Anonymous class: "+msg);
        }));
    }
	// 使用接口的方法
    public static void useStringHander(StringHandler stringHandler) {
        stringHandler.printMessage("Hello World");
    }

}

interface StringHandler {
    void printMessage(String msg);
}

2.1.2 Lambda 有参无返回值抽象方法

package com.fcarey.innerclass;

public class LambdaTest {
    public static void main(String[] args) {
        useStringHander(new StringHandler() {
            @Override
            public void printMessage(String msg) {
                System.out.println(msg);
            }
        });

        useStringHander((msg -> {
            System.out.println("Anonymous class: "+msg);
        }));
    }

    public static void useStringHander(StringHandler stringHandler) {
        stringHandler.printMessage("Hello World");
    }

}

interface StringHandler {
    void printMessage(String msg);
}

2.1.3 Lambda 无参有返回值抽象方法

package com.fcarey.innerclass;

import java.util.Random;

public class LambdaTest02 {
    public static void main(String[] args) {
        useRandomNumberHandler(new RandomNumberHandler() {
            @Override
            public int getNumber() {
                Random r = new Random();
                return r.nextInt(100);
            }
        });
        useRandomNumberHandler(()->{Random r = new Random();
            return r.nextInt(100);
        });
    }
    public static void useRandomNumberHandler(RandomNumberHandler randomNumberHandler){
        int result = randomNumberHandler.getNumber();
        System.out.println(result);
    }
}

interface RandomNumberHandler{
    int getNumber();
}

2.1.4 有参有返回值抽象方法

package com.fcarey.innerclass;

import java.util.Random;

public class LambdaTest03 {

    public static void main(String[] args) {
        useCalculator(new Calculator() {
            @Override
            public int calc(int a, int b) {
                return a+b;
            }
        });
        useCalculator((a, b) -> a+b);
    }

    public static void useCalculator(Calculator calculator) {
        Random rand = new Random();
        int a = rand.nextInt(100);
        int b = rand.nextInt(100);
        System.out.println(calculator.calc(a,b));;
    }
}

interface Calculator {
    int calc(int a, int b);
}

2.2 Lambda表达式的省略模式

省略的规则

  • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
  • 如果参数有且仅有一个,那么小括号可以省略
  • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字

2.3 Lambda表达式的使用前提

  • 使用Lambda必须要有接口
  • 并且要求接口中有且仅有一个抽象方法

2.4 Lambda表达式和匿名内部类的区别

  • 所需类型不同
    • 匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
    • Lambda表达式:只能是接口
  • 使用限制不同
    • 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
    • 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
  • 实现原理不同
    • 匿名内部类:编译之后,产生一个单独的.class字节码文件
    • Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

标签:JAVA,内部,void,System,class,println,public,Lambda
From: https://www.cnblogs.com/f-carey/p/18383523

相关文章

  • Java API:MATH
    JavaAPI:MATH目录JavaAPI:MATH1MATH2示例1MATHMath包含执行基本数字运算的方法;Math类提供的所有方法都是类方法;Math类方法变量和类型方法描述staticintabs(inta)返回int值的绝对值。staticdoubleceil(doublea)返回大于或等于参数且等于数学......
  • Java API:System
    JavaAPI:System目录JavaAPI:System1System2示例代码1SystemSystem类包含几个有用的类字段和方法。它无法实例化。System类提供的设施包括标准输入,标准输出和错误输出流;访问外部定义的属性和环境变量;加载文件和库的方法;以及用于快速复制阵列的一部分的实用方法。......
  • Java API:Object and Objects
    JavaAPI:ObjectandObjects目录JavaAPI:ObjectandObjects1Object1.1常用方法1.1Object类的toString方法1.1.1示例1.2equals1.2.1示例1.2.2面试题2Objects2.1示例1Object类Object是类层次结构的根。每个class都有Object作为超类。所有对象(包括数组)都实现此类的方......
  • Java API:BigDecimal
    JavaAPI:BigDecimal目录JavaAPI:BigDecimal1BigDecimal2示例1BigDecimalBigDecimal类使用户完全控制舍入行为。如果未指定舍入模式,并且无法表示确切的结果,则抛出异常;否则,可以通过向操作提供适当的MathContext对象来进行计算,以选择精度和舍入模式。在这两种情况下,都......
  • 浙江省会计人员继续教育刷课脚本-JavaScript编写
    脚本学习网站:浙江省会计人员继续教育:https://jxjy.czt.zj.gov.cn/front/jxjy.html脚本地址:浙江省会计人员继续教育-刷课脚本:https://greasyfork.org/zh-CN/scripts/506412-浙江省会计人员继续教育-刷课脚本教程1.插件安装(以MicrosoftEdge浏览器为例)打开最中间那个蓝色......
  • Java中的一些思想
    Java中的一些思想目录Java中的一些思想1分类思想2分包思想3类与类之间的访问4static关键字4.1static修饰的特点4.2注意事项5信息管理系统5.1系统说明5.1.1学生管理系统5.1.2老师管理系统5.2实现步骤5.3代码实现5.3.1Student5.3.2Teacher1分类思想分工协作,专人......
  • java ThreadLocal做线程隔离
    `ThreadLocal`类提供了线程局部变量,每个线程都可以独立地访问自己的变量副本,而不会影响其他线程的副本。这在多线程环境中非常有用,可以避免线程间的数据共享和竞争条件,提高程序的线程安全性。###ThreadLocal的用法:1.**创建ThreadLocal对象**:首先需要创建一个`ThreadLocal`......
  • java并发 第四章共享模型之管程 3 synchronized 原理
    1.轻量级锁轻量级锁的使用场景:如果一个对象虽然有多线程要加锁,但加锁的时间是错开的(也就是没有竞争),那么可以使用轻量级锁来优化。轻量级锁对使用者是透明的,即语法仍然是synchronized假设有两个方法同步块,利用同一个对象加锁 staticfinalObjectobj=newObject();......
  • 浙江省住房和城乡建设行业继续教育刷课脚本-JavaScript编写
    脚本学习网站:https://zj.zjjsrc.cn/web/web_toUserSignUp.page脚本地址:浙江省住房和城乡建设行业专业技术人员继续教育-刷课脚本:https://greasyfork.org/zh-CN/scripts/506406-浙江省住房和城乡建设行业专业技术人员继续教育-刷课脚本教程1.插件安装(以MicrosoftEdge浏览器......
  • 浙江省建设人才远程继续教育平台刷课脚本-JavaScript编写
    脚本学习网站:https://zj.zjjsrc.cn/web/web_toUserSignUp.page脚本地址:浙江省建设人才远程继续教育平台刷课脚本:https://greasyfork.org/zh-CN/scripts/506406-浙江省住房和城乡建设行业专业技术人员继续教育-刷课脚本教程1.插件安装(以MicrosoftEdge浏览器为例)打开最中间......