【8】java之引用传递
一、引用传递
引用传递是整个 java 的精髓所在
引用传递核心意义:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一块堆内存内容进行修改。
范例:第一道引用传递范例
class Message{
private int num = 10;
public Message(int num){
this.num = num;
}
public void setNum(int num){
this.num = num;
}
public int getNum(){return this.num;}
public int getInfo(){
return this.num;
}
} public class TestDemo{
public static void main(String args[]){
Message msg = new Message(30);
// 引用传递
fun(msg);
System.out.println(msg.getNum());
}
public static void fun(Message temp){
temp.setNum(100);
}
}
以上程序输出:100。
范例:第二道引用传递
public class TestDemo{
public static void main(String args[]){
String msg = "Hello";
// 引用传递
fun(msg);
System.out.println(msg);
}
public static void fun(String temp){
temp = "World";
}
}
以上输出:Hello,题目只有一个解决思路:String 类对象内容一旦声明则不可改变,对象内容的改变依靠的是引用关系的变更。
范例:第三道引用传递
class Message{
private String info = "nihao";
public Message(String info){
this.info = info;
}
public void setInfo(String info){
this.info = info;
}
public String getInfo(){return this.info;}
} public class TestDemo{
public static void main(String args[]){
Message msg = new Message("Hello");
// 引用传递
fun(msg);
System.out.println(msg.getInfo());
} public static void fun(Message temp){
temp.setInfo("World");
}
}
输出:World。但是以上的内存描述并不严格,因为在程序里,info 也是一个 String 类的对象。
结论:虽然 String 属于类,属于引用类型,但是由于其内容不可改变的特点,很多情况把 String 类型当成基本数据类型那样使用,也就是说:每一个 String 变量只能够保存一个数据。
总结:这三个引用范例算是一个小小的总结,也算是彻底阐述了 String 类的特点:不能改变。
二、引用传递实际应用
假如说,每一个人都有一辆车或没有汽车。如果设计满足以上数据存储的数据库,应该设计两张表:汽车表和人员表。
那么换回到程序思路,如果说现在想定义类,那么也应该定义两个类,所以通过分析可以发现以下的神奇规律:
简单 Java 类的编写原则:
- 类名称 = 表名称;
- 属性名称(类型) = 表字段(类型);
- 一个实例化对象 = 一行记录;
- 多个实例化对象(对象数组) = 多行记录;
- 引用关系 = 外键约束。
范例:代码设计如下
class Member{
private int mid;
private String name;
}
class Car{
private String cname;
}
以上实现了两个独立的类,并且没有外键关系,但是在表中可以通过外键描述关系,那么在类之中可以采用引用描述这个关系。
class Member{
private int mid;
private String name;
/* 表示属于人的车
如果 Car 有实例化对象则表示人有车;
如果 car 为 null 则表示人没有车。
*/
private Car car;
public String getInfo(){
return "编号:" + this.mid + ", 姓名:" + this.name;
}
}
class Car{
private String cname;
private Member member; // 车属于一个人
public Car(String name){
this.cname = name;
}
public String getInfo(){
return "汽车名字:" + this.cname;
}
}
一定要记住,Member 和 Car 应该都是一个独立的对象,而后通过产生对象发生关系。
当 Member 或 Car 类的对象产生之后,那么就应该为这两个对象设置彼此的关系。
class Member{
private int mid;
private String name;
/* 表示属于人的车
如果 Car 有实例化对象则表示人有车;
如果 car 为 null 则表示人没有车。
*/
private Car car;
public Member(int mid,String name){
this.mid = mid;
this.name = name;
}
public void setCar(Car car){
this.car = car;
}
public Car getCar(){
return this.car;
}
public String getInfo(){
return "编号:" + this.mid + ", 姓名:" + this.name;
}
}
class Car{
private String cname;
private Member member; // 车属于一个人
public Car(String name){
this.cname = name;
}
public void setMember(Member member){
this.member = member;
}
public Member getMember(){
return this.member;
}
public String getInfo(){
return "汽车名字:" + this.cname;
}
}
public class TestDemo{
public static void main(String args[]){
Member member = new Member(1,"King");
Car car = new Car("宝马");
member.setCar(car);
car.setMember(member);
System.out.println(member.getCar().getInfo());
System.out.println(car.getMember().getInfo());
}
}
以上的程序类完成之后,下面需要对程序进行测试,但是对程序的测试要求分两步:
- 第一步:根据定义的结构关系设置数据;
- 第二步:根据定义的结构关系取出数据。
public class TestDemo{
public static void main(String args[]){
// 第一步:设置数据
Member member = new Member(1,"King"); // 独立对象
Car car = new Car("宝马"); // 独立对象
member.setCar(car); // 一个人有一辆车
car.setMember(member); // 一辆车属于一个人
// 第二步:取出数据
System.out.println(member.getCar().getInfo()); // 通过人找到车的信息
System.out.println(car.getMember().getInfo()); // 通过车找到人的信息
}
下面进一步设计,例如:每个人都有自己的孩子,孩子还可能有车。
class Member{
private int mid;
private String name;
/* 表示属于人的车
如果 Car 有实例化对象则表示人有车;
如果 car 为 null 则表示人没有车。
*/
private Car car;
private Member child;
public Member(int mid,String name){
this.mid = mid;
this.name = name;
}
public void setCar(Car car){
this.car = car;
}
public Car getCar(){
return this.car;
}
public void setChild(Member child){
this.child = child;
}
public Member getChild(){
return this.child;
}
public String getInfo(){
return "编号:" + this.mid + ", 姓名:" + this.name;
}
} class Car{
private String cname;
private Member member; // 车属于一个人
public Car(String name){
this.cname = name;
}
public void setMember(Member member){
this.member = member;
}
public Member getMember(){
return this.member;
}
public String getInfo(){
return "汽车名字:" + this.cname;
}
} public class TestDemo{
public static void main(String args[]){
// 第一步:设置数据
Member member = new Member(1,"King"); // 独立对象
Car car = new Car("宝马"); // 独立对象
member.setCar(car); // 一个人有一辆车
car.setMember(member); // 一辆车属于一个人 Member child = new Member(2,"KAlice"); //一个孩子
Car carc = new Car("法拉利"); // 一辆车
member.setChild(child); // 一个人有一个孩子
child.setCar(carc); // 一个孩子有一辆车
carc.setMember(child); // 一辆车属于一个人
// 第二步:取出数据
System.out.println(member.getCar().getInfo()); // 通过人找到车的信息
System.out.println(car.getMember().getInfo()); // 通过车找到人的信息
System.out.println(member.getChild().getInfo()); // 通过人找到孩子的信息;
System.out.println(member.getChild().getCar().getInfo()); // 通过人找到孩子的车子信息;
}
}
现实中这样的操作其实很常见:一个人有一间房子、一个人有一张身份证、一个人有一个驾照......
还可以针对引用做进一步的描述,例如:要求描电脑,电脑由主机、显示器、键盘、CPU、鼠标、内存、硬盘、显卡组成。那么现在怎么通过代码描述呢?
以下是伪代码
class 键盘{}
class 鼠标{}
class 硬盘{}
class 显示器{}
class 主板{}
class 主机{
private 硬盘 对象[];
private CPU 对象[];
private 主板 对象;
private 内存 对象[];
}
class 电脑{
private 主机 对象;
private 显示器 对象[];
private 鼠标 对象;
}
这样的设计思路在 Java 之中称为合成设计模式。合成设计的关键:占着各自对象类型。
【8】java之引用传递的更多相关文章
- Java Object 引用传递和值传递
Java Object 引用传递和值传递 @author ixenos Java没有引用传递: 除了在将参数传递给方法(或函数)的时候是"值传递",传递对象引用的副本,在任何用&q ...
- Java参数引用传递之例外:null
今天写链表的时候写了一个函数,实参是一个空链表,应该是按引用传参,但是在函数内修改了链表,外部的链表没有变化. 原来是null作为参数传递的时候,就不是引用传参了. 引自:http://blog.cs ...
- Java没有引用传递机制,C#有。
Java没有引用传递机制,C#有: public class Obj { private Integer myValue; public Integer getMyValue() { return m ...
- Java中引用传递
//Java中的引用传递 class Ref1{ int temp = 10 ; String Str = "hello"; } public class HelloWorld { ...
- 有关java的引用传递,直接操作对象本身。直接删除BE的value中某值
HashSet<String> refRegions = BE.get(regionName); HashSet<String> values = new HashSet ...
- java中 引用传递、值传递的理解(数组,自定义类,基本数据类型,String类)
代码部分: public static void main(String[] args) { testInt(); testString(); testArray(); testX(); } publ ...
- 如何理解java的引用传递
1. 数组的引用传递 public class TestArray { public static void changeAry1(int[] ary){ int[] ary1 = {9,9,9}; ...
- (转)java中引用传递和值传递
https://blog.csdn.net/javazejian/article/details/51192130 https://www.cnblogs.com/perfy/archive/2012 ...
- java的引用传递
public class T{ static class Node{ int value; Node left = null; Node right = null; public Node(int v ...
- Java中的引用传递和值传递
Java中的引用传递和值传递 关于Java的引用传递和值传递,在听了老师讲解后,还是没有弄清楚是怎么一回事,于是查了资料,所以在这里与大家分享,有不对的地方,欢迎大家留言. java中是没有指针的,j ...
随机推荐
- SQL注入问题、视图、触发器、事物、存储过程、函数、流程控制、索引相关概念、索引数据结构、慢查询优化、
目录 SQL注入问题 视图 触发器 事物 存储过程 函数 流程控制 索引相关概念 索引数据结构 慢查询优化 测试装备 联合索引 全文检索 插入数据 更新数据 删除数据 主键 外键 重命名表 事物 安全 ...
- 微软跨平台maui开发chatgpt客户端
image 什么是maui .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动(ios,andriod)和桌面(windows,mac)应 ...
- 从面试题入手,畅谈 Vue 3 性能优化
前言 今年又是一个非常寒冷的冬天,很多公司都开始人员精简.市场从来不缺前端,但对高级前端的需求还是特别强烈的.一些大厂的面试官为了区分候选人对前端领域能力的深度,经常会在面试过程中考察一些前端框架的源 ...
- JavaScript:this指针
this指针,存储的是一个内存地址,如同变量一样,指向一块内存区域: 而这个内存区域,保存的就是一个对象的数据,那么这个对象是什么呢? 通常来说,this指针,主要是用在方法(函数)中,用来指向调用方 ...
- python之路38 SQL注入问题 索引触发器 事务 存储过程 函数 流程控制
SQL注入问题 怪像1:输对用户名就可以登录成功 怪像2:不需要对的用户名和密码也可以登录成功 SQL注入:利用特殊符号的组合产生特殊的含义 从而避开正常的业务逻辑 select * from use ...
- [深度探索C++对象模型]memcpy和memset注意事项
不管使用memcpy()还是memset(),都只有在"classes不含任何由编译器产生的内部members"时才能运行.如果这个类声明一个或者一个以上的virtual func ...
- Python对字典进行赋值操作时报错:“Cannot assign to function call”解决方案
今天编程时对字典进行赋值操作时报错"Cannot assign to function call": 翻译一下就是无法分配函数调用的空间. 我很纳闷,因为前面都可以正常调用dict ...
- 在线程里使用线程外的变量为什么一定要是final类型
public class CyclicBarrierDemo { public static void main(String[] args) { /* * 七龙珠 * */ CyclicBarrie ...
- 默认方法:negate-集合信息筛选
默认方法:negate "与"."或"已经了解了,剩下的"非"(取反)也会简单.默认方法negate的JDK源代码为︰ 集合信息筛选 数组当 ...
- 【分析笔记】全志 i2c-sunxi.c 控制器驱动分析
分析平台:全志 A64 内核版本:Linux 4.9 数据手册:Allwinner_A64_User_Manual_V1.1.pdf (whycan.com) 驱动框架 I2C 设备驱动 作为方案应用 ...