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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jenkins 配置节点交换内存

查看交换内存 free -hswapon -s创建swap文件 dd if/dev/zero of/mnt/swap bs1M count1024启用交换文件 设置权限 chmod 600 /mnt/swap设置为交换空间 mkswap /mnt/swap启用交换 swapon /mnt/swap设置用户组 chown root:root /mnt/swap查看 swapon -s重启系统也能生效还需要修…

简于外 强于内,联想全新ThinkCentre M90a Pro Gen4以强劲性能开启商

近日&#xff0c;联想发布了最新一代商用台式一体机联想ThinkCentre M90a Pro Gen4。作为联想ThinkCentre M大师系列的旗舰产品&#xff0c;其配备了优质的显示屏&#xff0c;拥有强大的性能和稳定安全的特性&#xff0c;能够满足多样的工作场合&#xff0c;为商用一体机的行业…

前端如何判空

这样判空就会报错 loadNode(node, resolve)console.log("node")console.log(node)if (node.data ! null) {this.get(ctx /publicity/publicityType/typeTreeData?id node.data.id).then((res) > {resolve(res)})}}, 需要这样写&#xff0c;用typeof来做类型判…

格式化名称节点,启动Hadoop

1.循环删除hadoop目录下的tmp文件&#xff0c;记住在hadoop目录下进行 rm tmp -rf 使用上述命令&#xff0c;hadoop目录下为&#xff1a; 2.格式化名称节点 # 格式化名称节点 ./bin/hdfs namenode -format 3.启动所有节点 ./sbin/start-all.sh 效果图&#xff1a; 4.查看节…

Vue中的$nextTick

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue中的$nextTick 目录 &#x1f40b;Vue中的$nextTick有什么作用&#xff1f; &#x1f40b;一、…

认知升级:成功需要掌握的思维模型

你好&#xff0c;我是 EarlGrey&#xff0c;一名双语学习者&#xff0c;会一点编程&#xff0c;目前已翻译出版《Python 无师自通》、《Python 并行编程手册》等书籍。 点击上方蓝字关注我&#xff0c;在后台回复“books”&#xff0c;即可领取超值优质电子书合集。 大家好&…

Docker安装Rabbitmq3.12并且prometheus进行监听【亲测可用】

一、安装Rabbitmq 下载镜像&#xff1a; docker pull rabbitmq:3.12-management 安装镜像&#xff1a; docker run -id --restartalways --namerabbitmq -v /usr/local/rabbitmq:/var/lib/rabbitmq -p 15692:15692 -p 15672:15672 -p 5672:5672 -e RABBITMQ_DEFAULT_USERgu…

Go语言多线程爬虫万能模板它来了!

对于长期从事爬虫行业的技术员来说&#xff0c;通过技术手段实现抓取海量数据并且做到可视化处理&#xff0c;我在想如果能写一个万能的爬虫模板&#xff0c;后期遇到类似的工作只要套用模板就能解决大部分的问题&#xff0c;如此提高工作效率何乐而不为&#xff1f; 以下是一个…

AUTOSAR实战篇:基于ETAS工具链的信息安全协议栈集成指南

AUTOSAR实战: 基于ETAS工具链的信息安全协议栈集成指南 前言 小T出品,必是精品! 手把手带你集成信息安全协议栈,你值得拥有! 正文 随着汽车信息安全的不断发展与完善,其在汽车电子领域如智能驾驶(ADAS),智能座舱等方向上不断被重视起来,越来越多的Tier1,主机厂都在全面…

枚举 蓝桥oj 小蓝和小桥的挑战

题目 分析 用一个postiveSum记录所有正数的和&#xff0c;一个negativeSum记录所有负数的和&#xff0c;一个zeroNums记录0的数量&#xff0c;count表示加1的数量 所有的0必须算在加1的数量里面&#xff0c;否则积必然为0 将所有0加1后加入positiveSum中&#xff0c;再比较正数…

利用叉积计算向量的旋向及折线段的拐向

一、向量叉积 两个向量 u u u、 v v v的叉积写作 u v n ∥ u ∥ ∥ v ∥ s i n θ \mathbf{u \times v n \left \| u \right \| \left \| v \right \| sin\theta } uvn∥u∥∥v∥sinθ 式中&#xff0c; n n n: 与 u u u、 v v v均垂直的单位向量&#xff0c;theta是两向量…

Servlet实现一个简单的表白墙网站

文章目录 前言效果展示事前准备HTML、CSS、JavaScript分别负责哪些HTML和CSS构架出页面的基本结构和样式JavaScript 实现行为和交互实现服务器端的业务代码整理pom.xmlweb.xmlmessageWall.htmlMessageServlet.java 前言 前面我们学习了 Java 中知名的 HTTP 服务器 tomcat 的安…