java 内部类(匿名类,匿名对象,静态内部类)详解及实例

Java内部类(匿名类,匿名对象,静态内部类)详解及实例

Java内部类是一个嵌套在其他类中的类,内部类可以访问外部类的所有成员(包括私有成员),并且可以用来实现一些特殊的功能。Java内部类通常分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。

成员内部类

成员内部类是定义在外部类的内部,并且不是 static 的内部类。成员内部类可以访问外部类的所有成员(包括私有成员),并且可以用来实现一些特殊的功能。例如,我们可以使用成员内部类来实现一个迭代器:

public class MyArrayList<T> {
    private T[] array;
    private int size;

    public MyArrayList() {
        this.array = (T[]) new Object[10];
        this.size = 0;
    }

    public void add(T value) {
        if (size >= array.length) {
            resize();
        }
        array[size] = value;
        size++;
    }

    public T get(int index) {
        return array[index];
    }

    public int size() {
        return size;
    }

    public void remove(int index) {
        for (int i = index; i < size - 1; i++) {
            array[i] = array[i+1];
        }
        size--;
    }

    public Iterator<T> iterator() {
        return new MyIterator();
    }

    private void resize() {
        T[] newArray = (T[]) new Object[array.length * 2];
        for (int i = 0; i < size; i++) {
            newArray[i] = array[i];
        }
        array = newArray;
    }

    private class MyIterator implements Iterator<T> {
        private int index;

        public MyIterator() {
            index = 0;
        }

        @Override
        public boolean hasNext() {
            return index < size;
        }

        @Override
        public T next() {
            T value = array[index];
            index++;
            return value;
        }

        @Override
        public void remove() {
            MyArrayList.this.remove(index-1);
            index--;
        }
    }
}

在上面的代码中,MyArrayList 类中包含了一个名为 MyIterator 的成员内部类,这个内部类实现了一个简单的迭代器,用于遍历 MyArrayList 中的元素。注意到在 MyIterator 中,可以直接访问外部类中的 array 和 size 等成员变量。

局部内部类

局部内部类是定义在方法内部的类。局部内部类只可以在定义类的方法中使用,其作用范围被限定在该方法内部,对外部是不可见的。局部内部类可以访问该方法的所有参数和方法变量,但要求这些变量必须是 final 类型的。例如,我们可以使用局部内部类来实现一个简单的计数器:

public class Counter {
    public static void main(String[] args) {
        System.out.println(count(10));
    }

    public static int count(int n) {
        class Counter {
            private int value;

            public Counter() {
                value = 0;
            }

            public void increment() {
                value++;
            }

            public int getValue() {
                return value;
            }
        }

        Counter counter = new Counter();

        for (int i = 0; i < n; i++) {
            counter.increment();
        }

        return counter.getValue();
    }
}

在上面的代码中,count 方法中定义了一个名为 Counter 的局部内部类,这个内部类实现了一个计数器,用于对参数 n 进行计数。在 count 方法中,我们可以创建一个 Counter 对象,并调用 increment 和 getValue 方法进行计数。

匿名内部类

匿名内部类是一种特殊的局部内部类,它在定义时没有完整的类名,通常只是使用一个接口或抽象类作为参数,然后在定义时直接实现其抽象方法。匿名内部类可以用来快速实现某些功能,例如实现一个简单的 OnClickListener:

public class Main {
    public static void main(String[] args) {
        Button button = new Button();
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick() {
                System.out.println("Button clicked!");
            }
        });
        button.click();
    }
}

interface OnClickListener {
    void onClick();
}

class Button {
    private OnClickListener onClickListener;

    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public void click() {
        if (onClickListener != null) {
            onClickListener.onClick();
        }
    }
}

在上面的代码中,我们定义了一个名为 Main 的类,其包含了一个点击按钮的示例。在 main 方法中,我们创建了一个 Button 对象,并使用匿名内部类实现了一个 OnClickListener 接口,用于当按钮被点击时输出一条信息。

静态内部类

静态内部类是定义在外部类内部,并且被声明为 static 的内部类。静态内部类可以访问外部类的所有静态成员,但是不能直接访问外部类的非静态成员(可以通过创建外部类对象来访问)。例如,我们使用静态内部类来实现一个简单的日志记录器:

public class Logger {
    private static List<String> logs = new ArrayList<>();

    public static void log(String message) {
        logs.add(message);
    }

    public static List<String> getLogs() {
        return logs;
    }

    public static class LoggerThread extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Logger.getLogs());
            }
        }
    }
}

在上面的代码中,我们定义了一个名为 Logger 的类,其包含了一个静态内部类 LoggerThread,用于定时输出日志信息。在 LoggerThread 类中,我们可以直接调用 Logger.getLogs 方法来获取日志信息,并在 run 方法中输出日志信息。

总结

Java 内部类是一种用于实现某些特殊功能的嵌套类。Java 内部类通常分为成员内部类、局部内部类、匿名内部类和静态内部类。以上面几个示例为例,它们分别使用了各种类型的 Java 内部类来实现一个迭代器、一个计数器、一个 OnClickListener 和一个日志记录器。使用内部类时需要考虑访问权限、变量的作用域和生命周期等问题,建议根据实际需要决定使用哪种类型的内部类。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java 内部类(匿名类,匿名对象,静态内部类)详解及实例 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java语言的优点是什么?

    Java语言的优点 Java是一种广泛使用的高级编程语言,由于具有很多优点,因此在软件开发领域中得到了广泛的应用。Java语言的优点包括: 1. 跨平台兼容性 Java语言的最大特点是跨平台兼容性。Java程序可以在任何支持Java虚拟机(JVM)的平台上运行,而不必担心操作系统的差异。编写一次,可以在多个平台上运行,这大大提高了开发效率。例如,以下代码可以…

    Java 2023年4月27日
    00
  • 详解用maven将dubbo工程打成jar包运行

    下面是详解用 Maven 将 Dubbo 工程打成 Jar 包运行的完整攻略。 1. 确认dubbo工程已经创建并可正常运行 首先,需要确认 Dubbo 工程已经创建并且能够正常运行。其中,建议使用 Java 8 或更高版本。 2. 在 pom.xml 文 件 中 增 加 打 包 插 件 配 置 在工程的 pom.xml 文件中,需要增加打包插件配置,以生成…

    Java 2023年5月20日
    00
  • Springmvc数据格式化原理及代码案例

    SpringMVC数据格式化原理及代码案例 在SpringMVC中,我们可以使用数据格式化器来将请求参数转换为Java对象或将Java对象转换为响应参数。本文将详细讲解SpringMVC数据格式化的原理及代码案例。 数据格式化原理 SpringMVC的数据格式化器是通过实现Converter接口或Formatter接口来实现的。Converter接口用于将一…

    Java 2023年5月18日
    00
  • 通用弹出层页面(兼容IE、firefox)可关闭控制宽高及屏蔽背景

    为了让大家更好地理解,我将会详细讲解如何实现“通用弹出层页面(兼容IE、firefox)可关闭控制宽高及屏蔽背景”。 1. 确定需求 首先,我们需要确定所需的样式和功能。需求如下: 弹出层需要兼容IE和firefox浏览器 弹出层需要能够控制宽度和高度 弹出层需要能够屏蔽背景 弹出层需要提供关闭按钮 2. 编写HTML代码 然后,我们需要在HTML文件中编写…

    Java 2023年6月15日
    00
  • 详解用maven搭建springboot环境的方法

    下面我将为您详细讲解如何用maven搭建springboot环境的方法。 1. 安装Maven Maven是一款软件项目管理工具,需要先安装它才能使用。建议下载官方版本进行安装。 2. 创建Maven项目 运行以下命令创建一个新的Maven项目: mvn archetype:generate -DgroupId=com.example -DartifactI…

    Java 2023年5月19日
    00
  • 浅谈一下Java中集合的迭代方式

    那我开始讲解“浅谈一下Java中集合的迭代方式”。首先介绍下迭代方式的概念,简单来说,迭代方式就是对集合进行重复操作的方式,它代表了一种遍历集合元素的能力。在Java中,主要有以下三种迭代方式: 1. foreach循环迭代 使用foreach循环迭代时,需要在循环头部声明一个与集合对象所存储元素类型相匹配的变量,然后在循环体中使用该变量进行操作: List…

    Java 2023年5月26日
    00
  • 在eclipse中中文汉字乱码的解决方案

    下面是在eclipse中解决中文乱码的完整攻略,包含以下步骤: 1. 修改eclipse编码格式 打开eclipse,找到菜单栏上的“Window”选项,然后点击“Preferences”。在弹出的窗口中,找到“General”选项,展开后点击“Workspace”。在右侧的“Text file encoding”下拉框中,选择“UTF-8”。然后点击下面的…

    Java 2023年5月19日
    00
  • jdk1.8的环境配置过程

    下面是 JDK 1.8 的环境配置过程攻略: 环境准备 在开始配置 JDK 1.8 之前需要先准备好以下内容: 一台已经安装好的计算机 从 Oracle 官网下载 JDK 1.8,并安装到计算机上 配置过程 配置环境变量 JDK 的环境变量配置非常重要,它可以让操作系统找到 JDK 安装路径。下面是配置 JDK 环境变量的方法: 打开“系统属性界面”(可以按…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部