Java中的指针

Java中是否有指针? 简短的答案是“不,没有”,这对于许多开发人员来说似乎是显而易见的。 但是,为什么对其他人却不那么明显呢?

  • http://stackoverflow.com/questions/1750106/how-can-i-use-pointers-in-java
  • http://stackoverflow.com/questions/2629357/does-java-have-pointers
  • https://www.google.hu/search?q=pointers+in+java

这是因为Java用于访问对象的引用与指针非常相似。 如果您有Java之前的C编程经验,则可能更容易考虑将变量中存储的值作为指向保存对象的某些内存位置的指针的想法。 或多或少都可以。 多于少,但这就是我们现在要看的。

引用和指针之间的区别

正如Brian Agnew在stackoverflow上总结的那样 ,有两个主要区别。

  1. 没有指针算法
  2. 引用不“指向”内存位置

缺少指针算法

当您在C中拥有一个struct数组时,为该数组分配的内存将一个接一个地包含结构的内容。 如果你有类似的东西

struct circle {double radius;double x,y;
}
struct circle circles[6];

它会在连续区域中占用6*3*sizeof(double)字节的内存(在64位体系结构中通常为144字节)。 如果您在Java中有类似的东西,则需要一个类( 直到我们使用Java 10或更高版本 ):

class Circle {double radius;double x,y;
}

和数组

Circle circles[6];

将需要6个引用(大约48个字节)和6个对象(除非其中一些为null),每个24bytes数据(大约)和对象标头 (16bytes)。 在64位体系结构上,总计288字节,并且存储区域不是连续的。

访问元素时,说出C语言数组的circles[n] ,代码将使用指针算术。 它使用存储在指针circles的地址加上nsizeof(struct circle) (字节),也就是数据所在的位置。

Java方法有些不同。 它查看对象circles ,它是一个数组,计算第n个元素(与C相似),并获取存储在其中的参考数据。 在参考数据可用之后,它使用它从参考数据所处的某个不同存储位置访问对象。

请注意,在这种情况下,Java的内存开销为100%,并且读取内存的次数为2而不是1,以访问实际数据。

引用不指向内存

Java引用不是指针。 它们包含某种指针数据或某些指针数据,因为它来自当今计算机体系结构的本质,但这完全取决于JVM实现,它存储在参考值中以及如何访问其引用的对象。 尽管不是很有效的实现,但是拥有一个巨大的指针数组(每个指针指向JVM的一个对象),并且引用是该数组的索引,这绝对是可以的。

实际上,JVM将引用实现为一种指针混合,其中某些位是标志,而某些位“指向”相对于某个区域的某个内存位置。

为什么JVM这样做而不是指针?

原因是垃圾回收。 为了实现有效的垃圾收集并避免内存碎片,JVM定期在内存中移动对象。 当由不再被引用的对象占用的内存被释放并且我们恰好在一个巨大的可用内存块中间有一个仍在使用和引用的小对象时,我们不希望该内存块被拆分。 取而代之的是,JVM将对象移动到另一个内存区域,并更新对该对象的所有引用以跟踪新位置。 一些GC实现会在发生这些更新时停止其他Java线程,以便没有Java代码使用未更新的引用而是移动了对象。 其他GC实现与底层OS虚拟内存管理集成在一起,从而在发生此类访问时导致页面错误,从而避免了应用程序线程的停止。

但是,问题是引用不是指针,而是JVM实现如何管理所有这些情况的责任。

与该领域密切相关的下一个主题是参数传递。

参数是通过值传递还是通过Java引用传递?

我在大学学习的第一门编程语言是Niklaus Wirth发明的PASCAL。 用这种语言,过程和函数参数可以通过值或引用来传递。 当参数通过引用传递时,则在过程或函数头中的参数声明之前带有关键字VAR 。 在使用函数的地方,不允许程序员将表达式写为实际参数。 您必须使用变量,并且函数(过程)中对参数的任何更改都将影响作为参数传递的变量。

当您使用语言C编程时,总是传递一个值。 但这实际上是一个谎言,因为您可能传递了指向该函数可以修改的变量的指针的值。 那就是当您将诸如char *s类的东西作为参数编写时,如果函数使用指针算术,则该函数可以更改s指向的字符或整个字符串。

在PASCAL中,值传递或引用传递的声明位于函数(或过程)的声明中。 在C语言中,您必须明确地编写一个类似于&s的表达式&s以将指针传递给变量s以便调用者可以对其进行修改。 当然,还必须声明该函数以使用指向s具有的任何类型s指针。

当您阅读PASCAL代码时,您无法在实际函数调用的位置知道参数是否按值传递,因此可能会被函数修改。 如果使用C,则必须在两个地方都进行编码,并且每当看到传递了参数值&s ,都可以确保该函数能够修改s的值。

Java到底是什么? 您可能对Java进行了多年编程,可能没有遇到这个问题或对此没有任何想法。 Java自动解决问题? 还是只是提供了一种非常简单的解决方案,以致不存在双重按值传递/引用方法?

可悲的事实是,Java实际上是隐藏了问题,并没有解决问题。 只要我们只处理Java通过引用传递的对象。 当结果是一个对象时,无论您写入实际函数调用中的任何表达式,对该对象的引用都将传递给该方法。 如果表达式是一个变量,则传递该变量包含的引用(这是变量的值,所以这是一种按值传递)。

当您传递基元( intboolean等)时,参数将按值传递。 如果所求值的表达式结果为原语,则按值传递它。 如果表达式是变量,则传递该变量包含的原始值。 这样一来,我们可以说看看三种示例语言

  • PASCAL声明如何传递参数
  • C计算传递给它的实际值
  • Java根据参数的类型决定

我认为Java有点混乱。 但是我没有意识到这一点,因为这种混乱局面是有限的,并且由于原语的盒装版本是不可变的,因此被很好地隐藏了。 如果无论如何都无法修改值,为什么还要关心参数传递的基本机制。 如果按值传递:可以。 如果它通过引用传递,则仍然可以,因为对象是不可变的。

如果装箱的原始值是可变的,是否会引起问题? 我们将查看是否以及何时将在Java中使用值类型 。

翻译自: https://www.javacodegeeks.com/2016/01/pointers-in-java.html

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

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

相关文章

Android实践 -- 监听应用程序的安装、卸载

监听应用程序的安装、卸载 在AndroidManifest.xml中注册一个静态广播,监听安装的广播android.intent.action.PACKAGE_ADDED 监听程序卸载的广播android.intent.action.PACKAGE_REMOVED ,在广播中一定要加上 <data android:scheme"package" /> 不然就监听不到 &…

符合c语言常量12abc,《C语言》试题abc合2006上.doc

《C语言》试题abc合2006上《c语言》试题(A)一、单项选择题(每小题2分&#xff0c;共20分)以下选项中正确的整型常量是 BA)12. B) -20 C) 1,000 D) 4 5 62.以下选项中不合法的用户标识符是 AA)abc.c B)file C)Main D)PRINT3&#xff0e;可在C 程序中用作用户标识符的标识符是 BA…

redis学习之——redis.conf配置(基本)文件学习

# Redis configuration file example# Note on units: when memory size is needed, it is possible to specify //1 配置大小单位,开头定义了一些基本的度量单位&#xff0c;只支持bytes&#xff0c;不支持bit …

如何把c语言程序的数据导出到文档,急求如何将下列C语言程序数据存储到文件中?...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼求如何改动才能将下列程序的存储输入或输出数据(或两者一起)到指定的文件(或运行时直接创立一个文件)如Arrangement中。#include int n0;int rest[7][7]; //全局声明,以供全局调用int main(){void perm(int list[],int ,int );int …

weblogic最大线程_处理Weblogic卡住的线程

weblogic最大线程定义或什么是缠线&#xff1f; 如果线程 在设定 的时间 内连续工作&#xff08;非空闲&#xff09;&#xff0c;则WebLogic Server会将其诊断为阻塞 。 您可以通过更改在诊断出线程被阻塞之前的时间长度&#xff08; Stuck Thread Max Time &#xff09;&#…

步进电机的正反向旋转c语言编程,实现步进电机自动正反转程序怎么写

本文收集整理关于实现步进电机自动正反转程序怎么写的相关议题&#xff0c;使用内容导航快速到达。内容导航&#xff1a;Q1&#xff1a;用c语言程序实现步进电机的正反转加减速的编程内容&#xff1a;1、本程序用于测试4相步进电机常规驱动2、需要用跳帽或者杜邦线把信号输出端…

常用容器(Collection)实现类总结(四)——HashSet

HashSet简略说明: 此类实现 Set 接口&#xff0c;由哈希表&#xff08;实际上是一个 HashMap 实例&#xff09;支持。它不保证 set 的迭代顺序&#xff1b;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。 (This class implements the Set interface, backed by a has…

Mockito验证

本文是我们名为“ 用Mockito进行测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的Stubbing行为。 您还将看到使用测试双打和对象匹配器进行验证的过…

js页面传值(注意中文)

页面a&#xff08;传送&#xff09;&#xff1a; var myUrlhttp://www.xxx?myParaencodeURI(中文参数);页面b&#xff08;接收&#xff0c;注意中文&#xff09;: //var myPara request("myPara"); function request(paras){// var url location.href;var urldeco…

stax 和jaxb 关系_XML解组基准:JAXB,STAx,Woodstox

stax 和jaxb 关系介绍 上周末&#xff0c;我开始考虑如何以一种资源友好的方式处理大量XML数据。我要解决的主要问题是如何以块的形式处理大型XML文件&#xff0c;同时提供上游/下游系统&#xff0c;需要处理一些数据。 当然&#xff0c;我已经使用JAXB技术已有几年了。 使用J…

C语言switch怎么算,超级新手,用switch写了个计算器程序,求指导

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼我也写过一个。。。。看样子大家都喜欢用 switch()来写计算机。。。。百度排版是渣渣&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;# includeintmain(void){ doublea, b, c;//a: 被X数&#xff0c; b: X数&#x…

vim编辑器初级(七)

:syntax on  打开语法高亮 :syntax off  关闭语法高亮 vim有两套语法颜色方案&#xff0c;分别用于背景亮和背景暗时&#xff0c;当vim启动时它会尝试辨别背景并选择合适的颜色方案&#xff0c;但vim辨别背景时可能出错 :set background?  查看background选项的值为多少…

如何编写Java代理

对于vmlens &#xff08;轻量级Java竞争条件捕获器&#xff09;&#xff0c;我们使用Java代理来跟踪字段访问。 这是我们学习的实现此类代理的经验教训。 开始 使用“ static public static void premain&#xff08;String args&#xff0c;Instrumentation inst&#xff09;…

48道C语言上机题参考答案,二级C语言上机题库参考答案(已修改).doc

二级C语言上机题库参考答案(已修改).doc下载提示(请认真阅读)1.请仔细阅读文档&#xff0c;确保文档完整性&#xff0c;对于不预览、不比对内容而直接下载带来的问题本站不予受理。2.下载的文档&#xff0c;不会出现我们的网址水印。3、该文档所得收入(下载内容预览)归上传者、…

Python练习-从小就背不下来的99乘法表

心血来潮,灵机一动,反正就是无聊的做了一个很简单的小玩意: for i in range(1,10):#让i 1-9 循环9次print("\n")#每循环一次进行一次换行for j in range(1,10):#让j 1-9 循环9次print(j, "x",i , "", i * j," ",end"")#输出…

快速排序 数组 函数 c语言,书上快速排序程序中子函数是怎样更改数组的?理论上不可实现啊...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼return不可能返回数组&#xff0c;于是子hanshu1quicksort最后没有用return&#xff0c;但是没有return又怎么可以更改a[N]&#xff1f;主函数中的quicksort(a, 0, N - 1);将a[N]复制后传递给形参a&#xff0c;quicksort(a, 0, N -…

(原创)SpringBoot入门

本文章是SpringBoot入门的介绍在这里 我会尽量写一些细节性的东西,我用的是IDEA2016 Tomcat7 JDK1.8 Maven3.3.9 IDEA Tomcat JDK Maven的安装我就不详细了, 这里我会提到Maven的安装和如何使用阿里云的镜像,因为官网的JAR下载真的是...比乌龟还慢 先从Maven的配置开始,到官…

jbox2d_JBox2D和JavaFX:事件与力量

jbox2d在昨天的示例中&#xff0c;您看到了如何创建一个简单的世界并使用WorldView进行显示&#xff0c;以及如何提供自定义渲染器。 现在&#xff0c;我们将添加一些用户输入。 我们将创建一个类似于弹球机中的鳍状肢的控件。 为此&#xff0c;我们将创建一个关节。 在JBox2D中…

整数因子分解c语言递归,整数因子分解:计算一个整数所有的分解式(递归实现)...

原始问题描述&#xff1a;对于给定的正整数n&#xff0c;计算n有多少种不同的分解式。例如&#xff0c;当n12时&#xff0c;有8种不同的分解式&#xff1a;1212,1262,1243,1234,12322,1226,12232 ,12223对n的每个因子递归搜索&#xff0c;代码如下&#xff1a;void solve (int …

Tomcat 部署了web项目中文乱码

本地Tomcat 启动&#xff0c;网页端的中文传到后台显示乱码。 查询前段已经设置了 UTF-8格式&#xff0c; 后台收到中文的依然是乱码&#xff0c;原来是Tomcat的配置问题。 修改Tomcat的配置文件server.xml &#xff0c;添加一个属性 URIEncoding"UTF-8"&#xff0c;…