Java引用和内部类

引用

引用变量

引用相当于一个 “别名”, 也可以理解成一个指针.

创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址.

new 出来的数组肯定是在堆上开辟的空间,那么在栈中存放的就是引用,引用存放的的就是一个对象的地址,代表指向关系.

int[]array2=array1;

就是在栈中再开辟一个空间作为引用,这两个引用存放的都是那个数组的地址.

总结: 所谓的 “引用” 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).

image-20231011215540178

java中引用必须初始化

如果确实不知道是哪块空间的引用,可以初始化为null

JVM内存空间分布

image-20231011220459714

  • 虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr 这样的存储地址的引用就是在这里保存.
  • 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
  • 堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2,3} )
  • 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域.
  • 运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量(字符串常量)与符号引用. (注意 从 JDK1.7 开始, 运行时常量池在堆上)
  • 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址.

image-20231011220731641

public class myArray {
    public static void main(String[] args) {
        int[] arr1={1,2,3,4,5};
        int []arr2=new int[]{5,4,3,2,1};

        int[]p1=arr1;
        int[]p2=arr2;

        p1[0]=100;
        p2[0]=100;

        System.out.println(arr1[0]);//100
        System.out.println(arr2[0]);//100
    }
    public static int[] tranform(int[]arr){//传的是引用,会将堆中数据改变
        int[] ret=new int[arr.length];//要想不被改变,再开一个空间计算返回
        for(int i=0;i<arr.length;i++){
            ret[i]=arr[i]*2;
        }
        return ret;
    }
}
多个引用指向同一个对象

image-20231011221525087

引用传参

image-20231011223509392

import java.util.Arrays;
public class myArray {
    public static void func1(int[]arr){//生成arr形参,引用中和arr1中指向同一个对象
        arr=new int[]{15,16,17,18};//arr更改指向对象
    }
    public static void func2(int[]arr){
        arr[0]=100;
    }
    public static void main(String[] args) {
        int[]arr1=new int[]{1,2,3,4};
//        func1(arr1);
        func2(arr1);
        System.out.println(Arrays.toString(arr1));//func1之后: 1 2 3 4
        //func2后: 100 2 3 4
    }
}

image-20231011222912130

image-20231011222929443

内部类

静态内部类

  • 无法直接访问外部类的非静态方法.
    • 可以创建外部类的对象,使用引用访问.
  • 外部类可以访问静态内部类中的所有的成员,即使在静态内部类中是private修饰的.
package demo1;

class OuterClass{
    public int data1=10;
    private int data2=20;
    public static int data3=30;

    public void test1(){
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(data3);

        InnerClass innerClass =new InnerClass();
        System.out.println(innerClass.data4);
        System.out.println(innerClass.data5);
        System.out.println(InnerClass.data6);//静态的用内部类类名访问,尽量避免使用对象
    }
    static class InnerClass{//静态内部类

        public int data4=40;
        private int data5=50;
        public static int data6=60;
        public void func(){
            //所有静态的,都是不依赖于对象的,所以无法访问OuterClass需要用引用访问的成员
//            System.out.println(data1);
//            System.out.println(data2);//error
            OuterClass outerClass =new OuterClass();
            System.out.println(outerClass.data1);
            System.out.println(outerClass.data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}
public class test1 {
    public static void main(String[] args) {
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
        innerClass.func();
        //10
        //20
        //30
        //40
        //50
        //60
    }
}

实例内部类

  • 在实例内部类中不能定义静态成员.彼此产生矛盾.

  • 实例内部类的实例化对象需要 外部类对象 调用才能实现.

  • 当内部类中存在和外部类成员变量名字冲突时,this肯定是内部类的.如果想要访问外部类的,需要使用

    OuterClass.this.data1

  • 当外部类加载时,这个非静态内部类是不会加载的

class OuterClass2{
    public int data1=10;
    private int data2=20;
    public static int data3=30;

    public void test1(){
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(data3);

        InnerClass2 innerClass2 =new InnerClass2();
        System.out.println(innerClass2.data4);
        System.out.println(innerClass2.data5);
        System.out.println(InnerClass2.data6);//使用类名访问
    }
    class InnerClass2{//非静态内部类(实例内部类)

        public int data1 = 1111;
        public int data4=40;
        private int data5=50;
//        public static int data6=60;//内部类是依赖于外部类对象的,静态的是不依赖于对象的,产生矛盾
        public static final int data6=60;//此时data6是常量,是在程序编译时就已经确定的
        public void func(){
            System.out.println(data1);//1111 this是内部类的this
            System.out.println(OuterClass2.this.data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
}
public class test1{
    public static void main(String[] args) {
        OuterClass2 outerClass2 = new OuterClass2();//此时的实力内部类可以理解为外部类的一个成员,需要对象调用
        OuterClass2.InnerClass2 innerClass2 =outerClass2. new InnerClass2();
        innerClass2.func();
        outerClass2.test1();
    }
}

匿名内部类

interface IA{
    void func();
}
class AA implements IA{
    @Override
    public void func() {
        System.out.println("AA func!");
    }
}
public class test1{
    public static void main(String[] args) {
        new IA(){//有一个类,实现了IA接口,重写了func函数,但是这个类没有名字.不会生成字节码文件
            @Override
            public void func() {
                System.out.println("hello 匿名内部类!");
            }
        }.func();//hello 匿名内部类!
    }
    public static void main1(String[] args) {//正常实现接口
        IA ia = new AA();
        ia.func();//AA func!
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/180245.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中部A股第一城,长沙如何赢商?

文|智能相对论 作者|范柔丝 长沙的马路&#xff0c;都很有故事。 一条解放西路&#xff0c;是全国人民都争相打卡的娱乐地标&#xff1b;一条太平街&#xff0c;既承载了历史的厚重又演绎着现代的鲜活...... 但如果来到河西的桐梓坡路&#xff0c;风景会变得截然不同。 沿…

Javascript中的宏任务与微任务

事件循环 JavaScript 语言的一大特点就是单线程&#xff0c;也就是说&#xff0c;同一个时间只能做一件事。为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为&#xff0c;防止主线程的不阻塞&#xff0c;Event Loop 的方案应用而生。Event Loop 包含两类&#xff1a;一…

[Linux 基础] Linux使用git上传gitee三板斧

文章目录 1、使用git1.1 安装git1.2 在Gitee上创建项目1.2.1 使用Gitee创建项目1.2.2 上传本地代码到远端仓库 1.3 git上传三板斧1.3.1 三板斧第一招&#xff1a;git add1.3.2 三板斧第二招&#xff1a;git commit1.3.3 三板斧第三招&#xff1a;git push 1、使用git 1.1 安装…

01 第一个C++程序:Hello, World!

系列文章目录 01 第一个C程序&#xff1a;Hello, World! 目录 系列文章目录 文章目录 前言 二、创建项目 三、书写代码 代码逐行解释 其它细节 总结 前言 这是c入门的第一个程序。 一、配置c环境 我们要使用visual studio创建一个新的项目时&#xff0c;需要安装c, 这里我没…

大数据分析仓库Kylin

一、Kylin 定义 Apache Kylin 是一个开源的分布式分析引擎&#xff0c;提供 Hadoop/Spark 之上的 SQL 查询接口及多维分析能力以支持超大规模数据&#xff0c;最初由 eBay 开发并贡献至开源社区。它能在亚秒内查询巨大的 Hive 表。 二、Kylin 架构 A、REST Server 是应用程序…

透过一台电视,看到万家星闪

此前我们说过&#xff0c;实现万物互联的梦想&#xff0c;不仅要关注光纤、5G所打通的智能联接&#xff0c;更要关注短距传输所支撑的最后一段距离。 在咫尺之间&#xff0c;方寸之地&#xff0c;数据的传输与设备的协同依旧会遇到大量挑战。反过来说&#xff0c;一旦出现稳定、…

为企业解决设备全生命周期需求,凌雄科技凸显DaaS增长价值

企业成长离不开投资&#xff0c;但毫无疑问的是&#xff0c;投资最有价值的部分在业务。相比之下&#xff0c;诸如办公设备之类的固定资产投资&#xff0c;很容易变成企业现金流的吞噬者。从购买、运维到保养、折旧、回收&#xff0c;现代企业在越来越大的办公设备规模面前&…

利用GenericMenu创建上下文菜单或下拉菜单

使用GenericMenu 创建自定义上下文菜单和下拉菜单丰富自己的编辑器功能。 GenericMenu 介绍 变量 allowDuplicateNames 允许菜单具有多个同名的菜单项。 公共函数 AddDisabledItem 向菜单添加已禁用的项。 AddItem 向菜单添加一个项。 AddSeparator 向菜单添加一个分隔符项…

优化器的选择

优化器使用SDG和Adam的loss也不同 每个文件夹大概包含的图片&#xff1a; 在这种数量级下的图像分类优先选择SDG。

使用原生js通过ajax实现服务器渲染的简单代码和个人改进

文章目录 前文提要代码实现主要参考服务器渲染实现逻辑网页呈现效果 代码分段讲解提要html的body部分css部分js部分xhr.open函数AJAX-onreadystatechange事件function函数简写方法附件功能&#xff1a;选中行 高亮 代码全文 前文提要 本文仅做个人学习记录&#xff0c;如有错误…

数字化转型过程中面临最大的问题是什么?如何借助数字化工具实现快速转型?

在科技快速发展的时代&#xff0c;数字化转型已经成为企业的重要战略。当企业努力适应数字化时代并取得成功时&#xff0c;他们可能会面临各种必须有效应对的挑战。   数字化转型不仅仅是将新技术应用到企业的运营中&#xff0c;还需要对企业的运营方式、与客户的互动方式和价…

多篇论文介绍-可变形卷积

01 具有双层路由注意力的 YOLOv8 道路场景目标检测方法 01 摘要: 随着机动车的数量不断增加&#xff0c;道路交通环境变得更复杂&#xff0c;尤其是光照变化以及复杂背景都会干扰目标检测算法的准确性和精度&#xff0c;同时道路场景下多变形态的目标也会给检测任务造成干扰&am…

计算机视觉的应用19-基于pytorch框架搭建卷积神经网络CNN的卫星地图分类问题实战应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用19-基于pytorch框架搭建卷积神经网络CNN的卫星地图分类问题实战应用。随着遥感技术和卫星图像获取能力的快速发展&#xff0c;卫星图像分类任务成为了计算机视觉研究中一个重要的挑战。为了促进这一…

使用Python的turtle模块创建一幅哆啦A梦

1.1引言&#xff1a; 在Python中&#xff0c;turtle模块是一个非常有趣且强大的工具&#xff0c;它允许我们以一个可视化和互动的方式学习编程。通过调用各种命令&#xff0c;我们可以引导turtle画出一个指定的图形。在本博客中&#xff0c;我们将使用turtle模块来绘制一幅哆啦…

UML建模图文详解教程01——Enterprise Architect安装与使用

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Enterprise Architect概述 官方网站&#xff1a;https://www.sparxsystems.cn/products/ea/&#xff1b;图示如下&#xff1a; Enterprise Architect是一个全功能的、基于…

IDEA中注释快捷键及模板

单行注释 将光标放置于要注释所在行&#xff0c;使用 Ctrl /&#xff0c; 添加行注释&#xff0c;再次使用&#xff0c;去掉行注释 若需要将多行进行单行注释&#xff0c;只需要选中要注释的多行&#xff0c;然后使用 Ctrl /&#xff0c; 添加行注释&#xff0c;再次使用&a…

【Linux】权限理解【文件权限以及目录权限详解、以及umsk程序掩码知识详解】

权限理解 一、Linux权限的概念二、su [用户名] &#xff1a; 切换用户三、Linux权限管理文件&#xff08;一&#xff09;文件访问者的分类&#xff08;人&#xff09;&#xff08;二&#xff09;文件类型和访问权限&#xff08;事物属性&#xff09;&#xff08;1&#xff09;第…

【开源】基于JAVA的在线课程教学系统

项目编号&#xff1a; S 014 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S014&#xff0c;文末获取源码。} 项目编号&#xff1a;S014&#xff0c;文末获取源码。 目录 一、摘要1.1 系统介绍1.2 项目录屏 二、研究内容2.1 课程类型管理模块2.2 课程管理模块2…

tp8 使用rabbitMQ

php8.0 使用 rabbitmq 要使用 3.6版本以上的&#xff0c; 并且还要开启 php.ini中的 socket 扩展 php think make:command SimpleMQProduce //创建一个生产者命令行 php think make:command SimpleMQConsumer //创建一个消费者命令行 生产者代码 <?php declare (strict_ty…

SpringBoot:异步任务基础与源码剖析

官网文档&#xff1a;How To Do Async in Spring | Baeldung。 Async注解 Spring框架基于Async注解提供了对异步执行流程的支持。 最简单的例子是&#xff1a;使用Async注解修饰一个方法&#xff0c;那么这个方法将在一个单独的线程中被执行&#xff0c;即&#xff1a;从同步执…