Java开发——7.内存分配(堆、栈以及参数的值传递+引用传递)

内存:

内存是计算机中的重要原件,临时存储区域,作用是运行程序。
我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的。
必须放进内存中才能运行,运行完毕后会清空内存。
Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。

此处补充内存和硬盘的区别:

1.内存是指安装在系统板上的随机存取内存,而硬盘驱动器是磁盘的主轴,也称为硬盘。

2.内存容量范围从 128 MB 到 4 GB,而硬盘容量范围从 320 GB 到 1TB。

3.内存中的存储类型是临时的(如果一断电内存中的数据就会丢失),而硬盘中的存储类型是永远。

4.内存:不允许我们存储个人数据;而是用于存储计算机数据。它读取和写入数据,并且会继续保存在内存,除非系统关闭。硬盘是一种可预测的存储器,可以让用户存储和擦除数据;存储在硬盘上的所有数据在使用期间和使用后都不会自动清除。

拓展:

RAM,一般指随机存取存储器。
随机存取存储器(英语:Random Access Memory,缩写:RAM),也叫主存,是与CPU直接交换数据的内部存储器。RAM即大家常说的运行内存,简称运存,是一种在手机中用来暂时保存数据的元件,相当于电脑中的内存条。

Java中的内存分配:

寄存器

给CPU使用。

寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。

本地方法栈

JVM在使用操作系统功能的时候使用,和我们开发无关。
Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用。

方法区

存储可以运行的.class文件,是各个线程共享的内存区域;方法区有垃圾回收机制

它存储已被Java虚拟机加载的类信息、常量、静态变量、编译器编译后的代码等。

堆内存

存储对象或者数组,用new关键字来创建的对象/数组都存储在堆内存。(“此处很好的解释了引用传递”.)

方法栈

方法运行时使用的内存,比如main方法运行,进入方法栈中执行。因为我们写的程序都默认保存在硬盘中,所以当程序运行的时候要进入到内存中。

public class Demo{
    public static void main(String []args){
    
      int num = 5;
      int arr [] = new int []{1,2,3};
    
    }
}
栈内存:

一般存放基本数据类型的值;当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆内存:

一般存放引用数据类型的值;在栈中存储的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。

//例如:
int arr [] = new int []{1,2,3};

int sum = arr[2];// sum就是一个变量。

而数组和对象本身仍存放在堆内存中,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在一个不确定的时间被垃圾回收器释放掉才能彻底释放内存。
这个也是Java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

在这里插入图片描述

值​传递的本质:

在参数传递的过程中,原来参数值不会发生改变!

public static void main(String[] args) {
//num 就是实参:实参是定义在方法之外类之中
        int num = 15;
        System.out.println("值传递之前:"+num);
        zhiChuanDi(num);
        System.out.println("值传递之后:"+num);
}public static void zhiChuanDi(int number){
//此处的number 就是形参:形参是定义在方法之中的
        number = 150;
    }

​图解分析:
主要原因:方法存储在栈内存中的,栈内存中的方法会随着方法的调用完成而消失;所以尽管num被当做参数传进了zhiChuanDi()的有参方法中,并且发生了重赋值的步骤,但是整个过程并不会影响原来的num实参。相当于复制了一份num,并把复制后的num当做形参传递给了zhiChuanDi()的有参方法​,实际的num是不变的。

在这里插入图片描述

​引用传递的本质:

在进行参数传递的过程中,发生了​参数值的改变。

public static void main(String[] args) {
        int arr[] = new int[]{12,18,20};
        System.out.println("引用传递之前:"+arr[0]);yinYongChuanDi(arr);
        System.out.println("引用传递之后:"+arr[0]);String str = "小红";
        System.out.println("引用传递之前:"+str);yinYongChuanDi2(str);
        System.out.println("引用传递之后:"+str);}
    public static void yinYongChuanDi(int []arr){
        arr[0] = 66;
    }
    public static void yinYongChuanDi2(String str){
        str = "小明";
    }

图解分析:
这个过程相当于,人的名字一样;大多数人的名字都会重复,但是每个人对应的身份证是不同的!因为new对象,对象的值是存在于堆内存中的,要想获取堆内存中的具体指,是通过底层的地址值进行访问的,所以以参数传过去的arr数组,实际上是传的一个具体实际的arr数组,所以对arr[0]进行参数重赋值的过程,是对底层​堆内存中的数据进行修改的;所以数据在进行参数传递的过程中发生了改变。
在这里插入图片描述

​但是:我下面举了一个例子,是String类型的字符串,在进行参数的传递过程中,值并没有发生改变。虽然String类型也是引用数据类型,但是他发生参数传递的过程相当于基本数据类型,因为他并没有new一个对象​!所以此处的String为特殊例子。
欢迎关注微信公众号:小红的成长日记,一起学Java!
欢迎关注微信公众号:小红的成长日记,一起学Java!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,我们需要使用Java中的DOM或SAX解析器来读取XML文件。接下来,我们可以将XML文件中的参数传递给接口,并获取返回内容。 以下是一个示例代码,演示了如何读写XML文件,并将XML中的参数传递给WishPost请求物流单号的接口: ```java import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class WishPostRequest { private static final String REQUEST_URL = "https://tracking.postoffice.co.za/VTI_Query1.asmx"; public static void main(String[] args) { try { // 读取XML文件 InputStream is = WishPostRequest.class.getResourceAsStream("wishpost_request.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(is); // 获取XML中的参数 NodeList nList = doc.getElementsByTagName("Param"); String trackingNumber = ""; for (int i = 0; i < nList.getLength(); i++) { Element element = (Element) nList.item(i); if (element.getAttribute("ParamName").equals("TrackNum")) { trackingNumber = element.getTextContent(); break; } } // 构造请求 URL url = new URL(REQUEST_URL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setUseCaches(false); conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "text/xml"); conn.setRequestProperty("SOAPAction", "http://tempuri.org/VTI_Query1"); // 将参数写入请求体 OutputStream os = conn.getOutputStream(); String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" + "<soap:Body>" + "<VTI_Query1 xmlns=\"http://tempuri.org/\">" + "<TrackNum>" + trackingNumber + "</TrackNum>" + "</VTI_Query1>" + "</soap:Body>" + "</soap:Envelope>"; os.write(xml.getBytes()); os.flush(); os.close(); // 发送请求并获取返回内容 InputStream response = conn.getInputStream(); // 处理返回内容 } catch (Exception e) { e.printStackTrace(); } } } ``` 在上述代码中,我们首先读取了一个名为"wishpost_request.xml"的XML文件。该文件包含了我们需要传递给接口的参数。接下来,我们使用DOM解析器解析了XML文件,并获取了名为"TrackNum"的参数。 接着,我们构造了一个HTTP POST请求,并将参数写入请求体。最后,我们发送请求并获取返回内容。在实际应用中,我们需要根据返回内容进行相应的处理。 需要注意的是,上述代码仅为示例代码,实际应用中还需要进行错误处理、异常处理等相关操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值