范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

为什么说函数只存在值传递ampampamp引用类型是什么

  1. 例子一
  我们先来看几个例子. 先来Java的吧. Java最假了. 一般人都认为是引用传递(基本类型值传递). 所以我们又拿C++做例子.
  写 a , b 是为了好区分开. 其实 写俩a都行. 不好书面表达 public class Demo {      public static void main(String[] args) {         A a = new A();         System.out.println("初始化 : " + a.name);         a.name = "main";         System.out.println("init函数调用前 : " + a.name);         // change 函数传递         init(a);         // 结果 ?         System.out.println("init函数调用后 : "+a.name);     }      static void init(A b) {         // a被初始化了..         b = new A();     }      private static class A {         String name;     } }
  输出 : 初始化 : null init函数调用前 : main init函数调用后 : main
  结果是啥. 如果真的是引用传递. 那么为啥a.name为啥不是空呢.
  我用C++ 给大家写一下.
  ```c++ includeinclude
  using namespace std;
  class A { public: string name; };
  void init(A *b) { cout << "未改变的地址 : " << b << endl; *b = A(); cout << "改变后的地址 : " << b << endl; } int main(int argc, char const *argv[]) { A *a = new A(); cout << "初始化 : " << a->name << endl; a->name = "main"; cout << "init函数调用前 : " << a->name << endl; init(a); cout << "init函数调用后 : " << a->name << endl; return 0; } ```
  输出 初始化 :  init函数调用前 : main 未改变的地址 : 0xe699d0 改变后的地址 : 0xe699d0 init函数调用后 :
  显然C++和Java的表现是不一样的. 为什么C++ 赋值可以改变值. 而Java却不是呢.
  我们先解释C++的做法.
  我们 init(A *b)  做了啥
  首先是我们定义了一个变量 A *a=new A("main") , 我没有写构造函数, 假设的.
  此时传递给函数 init(A *b)   , 此时 b=a ,a= 0xe699d0 . 所以呢 b= 0xe699d0 .
  后面我们的操作就是基于这个 b 的. 此时我们将 *b =A();   , 是不是将0xe699d0指针  指向了 A()   对象呢(其实就是块内存,指向的是内存的首地址) . 此时是不是修改了0xe699d0指针   的指向呢. 那么a也等于 0xe699d0 .所以a的值也被修改了 .
  然后我们看看Java的做法. static void init(A b) {     System.out.println("未改变的地址: 0x"+Integer.toHexString(a.hashCode()));     // a被初始化了..     b = new A();     System.out.println("改变后的地址: 0x"+Integer.toHexString(a.hashCode())); }
  我们打印一下 hashcode. 因为Java的hashcode其实就是确定一个对象的唯一标识, 如果你想深入了解hashcode的话介意看看JVM的源码,C++和Java对象的映射关系 (如果是对象地址的话,那么内存回收会改变大量的内存地址,难道还是地址吗,我们这里不考虑这个.只要知道这个是Java对象的唯一值类似于hash码 ).
  输出结果: 初始化 : null init函数调用前 : main 未改变的地址: 0x6e8cf4c6 改变后的地址: 0x12edcd21 init函数调用后 : main
  此时我们发现地址发生了改变. 其实理解了上面C++那部分聪明的就明白了.
  由于Java引用类型传递如果是Hotspot虚拟机则实现的就是简单的指针传递. 这个变量指向Java对象的数据区域.
  由于一开始 a=0x6e8cf4c6(Java引用对象) , 然后函数赋值 b=a , 此时 b= 0x6e8cf4c6.
  关键点在于new A()地方; 执行的是,实例化一个A对象,在栈顶开辟一块空间, 将A对象保存在栈顶中, 此时栈顶值=0x12edcd21, 然后将栈顶值存入到变量b中. 此时b=0x12edcd21 . 那么改变原来0x6e8cf4c6指向的内容了吗,并没有.
  我们再看看javac编译后的结果 : static void init(com.jvm.reference.Demo$A); descriptor: (Lcom/jvm/reference/Demo$A;)V flags: ACC_STATIC Code: // 栈的深度需要3 , 变量表需要一个,参数一个   stack=3, locals=1, args_size=1       // 实例化一个对象      0: new           #2                  // class com/jvm/reference/Demo$A      3: dup      4: aconst_null      // 调用构造方法      5: invokespecial #3                  // Method com/jvm/reference/Demo$A."":(Lcom/jvm/reference/Demo$1;)V      // 将栈顶值存入变量0中      8: astore_0      // 返回      9: return
  准确点说Java的做法是 : 如下操作. void init(A *b) {     cout << "未改变的地址 : " << b << endl;     A a = A();     b = &a;     cout << "改变后的地址 : " << b << endl; }
  其实各种做法也有各种做法的好处. 没有绝对的好坏.  2. 例子二
  其实你理解上面这个例子. 你就明白了为啥值传递了. 我们继续拿C++说话. Java查看地址不方便.  #include   using namespace std;  void swap(int *a, int *b) {     int *temp = a;     a = b;     b = temp;     cout << "a : " << *a << " , b : " << *b << endl; }  int main(int argc, char const *argv[]) {     int x = 1;     int y = 2;      cout << "x : " << x << " , y : " << y << endl;     // swap 方法.     swap(&x, &y);      cout << "x : " << x << " , y : " << y << endl;     /* code */     return 0; }
  输出 x : 1 , y : 2 a : 2 , b : 1 x : 1 , y : 2
  我们发现为啥函数内部 . a 和 b 成功交换了地址 . 所以 a 和 b的值就互换了 .
  但是为啥呢.
  我们再次打印一下地址 cout << "&x  : " << &x << " , &y : " << &y << endl; // 输出 :  &x : 0x61fefc , &y : 0x61fef8
  &x = 0x61fefc , &y=0x61fef8 ,
  执行swap函数. 此时 a=0x61fefc , b=0x61fef8 ,
  然后经过一番操作, 此时 a=0x61fef8 , b=0x61fefc . 然后输出 *a=2, *b=1, 所以成功了.
  但是为啥 x 和 y 没变呢. 是不是发现 &x 和 &y依旧着原来的地址呢.
  正确的swap操作 , 必须修改指针指向的值. void swap(int *a, int *b) {     int temp = *a;     *a = *b;     *b = temp; }3. Java的引用类型
  创建对象自然是为了后续使用该对象,我们的Java程序会通过栈上的reference数据来操作堆上的具体对象。由于 reference类型 在《Java虚拟机规范》里面只规定了它是一个指向对象的引用 ,并没有定义这个引用应该通过什么方式去定位、访问到堆中对象的具体位置,所以对象访问方式也是由虚拟机实现而定的,主流的访问方式主要有使用句柄和直接指针两种:如果使用句柄访问的话,Java堆中将可能会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自具体的地址信息,其结构如图2-2所示。 如果使用直接指针访问的话,Java堆中对象的内存布局就必须考虑如何放置访问类型数据的相关信息 ,reference中存储的直接就是对象地址,如果只是访问对象本身的话,就不需要多一次间接访问的开销,如图2-3所示。
  本文第三节引用自 <<深入理解Java虚拟机>> . 这两种对象访问方式各有优势 :
  使用句柄来访问的最大好处就是reference中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要被修改。
  使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销,由于对象访问在Java中非常频繁,因此这类开销积少成多也是一项极为可观的执行成本,就本书讨论的主要虚拟机HotSpot而言,它主要使用第二种方式进行对象访问(有例外情况,如果使用了Shenandoah收集器的话也会有一次额外的转发,具体可参见第3章),但从整个软件开发的范围来看,在各种语言、框架中使用句柄来访问的情况也十分常见。
  所以句柄访问方便管理, 直接指针访问效率高, 但是不方便管理.

面试官连这些问题都不知道?就想要50k?前言本人2016年毕业,目前从事Android开发工作已经3年啦。就是尘世间一个迷途小开发,二流程序员,居身于小城市,最终也是考虑到发展前景的局限性,趁着自己还年轻,于是毅然裸辞,相互宝关停的背后编辑导语近日,相互宝宣布将于2022年关停,因为这一消息,业内关于互联网互助平台的发展又展开了新一轮的讨论。为什么互联网互助平台的发展总是容易遇到商业变现上的困难?本文作者结合自己英特尔道歉,华为鸿蒙汽车问世!国产CPU的出路国产品牌一度崛起,我们的眼里只有国家的物品,国产我们一直都知道很好用,又很实惠。但是呢,总有一个搅屎棍英特尔。英特尔公司它要求供应商不要使用我们新疆的产品,英特尔这又是遭受了什么委华为Mate50Pro开始发力华为作为相当优秀的国产手机品牌,因为强悍的实力,优秀的品质,深受国内外用户欢迎。如果没有被制裁,华为将成为全球最受欢迎的手机厂商,市场占有率将会大大提升,全面超越三星和苹果。不过事望眼欲穿,iphoneSE3要来了,搭载A15处理器,支持5G网络自2020年4月15日发布iphoneSE2后,果粉们整整等了1年,iphoneSE3还是没有出现。苹果的SE系列机型机身小巧,价格实在,性能强悍,很受小屏爱好者的青睐。iPhon36氪首发从SDWAN延展到安全运维业务,七云网络完成数千万元的A轮融资36氪获悉,SDWAN及网络运维解决方案服务商七云网络已于日前完成A轮融资。本轮融资金额在数千万元级别,由维思资本领投,老股东常春藤资本和炬成资本继续加码,毅仁资本担任独家财务顾问判断是否装了QQ判断是否装了QQpublicstaticbooleanisQQClientAvailable(Contextcontext)finalPackageManagerpackageMa打造2万亿电商平台,马云却预言新零售会替代电商,提前投资700亿现如今,随着懒人经济的崛起,网上购物已经成了大家买东西的主要方式,而之所以可以享受这一方式,主要就是靠着马云花费2万亿打造的电商平台。值得注意的是,近两年马云又将目光放到了新零售领为什么很多人买手机只关注高端旗舰机?为什么有些人要买贵手机在买手机这件事上,买贵的手机是如何定义的,我觉得应该是这么理解,为什么很多人买手机只关注高端旗舰机。或者只看苹果手机,或者只看华为手机!因为这些手机价格都基本网站如何识别爬虫来访作为网站管理者,本着对网站数据客观详实的原则,是需要把爬虫带来的问题及时修复掉的,那核心问题就是网站如何识别爬虫来访?识别方案获取网页请求的useragent信息,使用特定标识判断互联网2021作者李好零九编辑钊岁末已至,是结束也是开始。2021年互联网圈的那些大事件,你还记得吗?反垄断社区团购广告行业增速放缓直播带货主播被罚刚送走庚子年的疫情,互联网行业还是没能继续大放
中韩手机品牌在俄竞争激烈来源环球时报环球时报报道根据俄罗斯电信运营商MTS公司10月份俄罗斯智能手机销售数据,韩国三星10月夺回俄智能手机市场销量头名,市场份额为34。5。整个三季度该公司销售数量低于中国新机OPPOFindX5iPhone13开始取消SIM卡荣耀折叠屏手机OPPOFindX5系列爆料今日微博博主数码闲聊站发布消息,透露了OPPOFindX5手机的部分消息。该系列暂定有三款机型,将搭载天玑9000骁龙8Gen1双平台。此外,OPPO继常程之后,雷军再次宣布小米12系列出厂预装MIUI1312月28日消息,早前小米集团副总裁常程今天发微博宣布小米12系列出厂预装MIUI13,可能是关注的人不多,于是小米创办人董事长兼CEO金山软件董事长天使投资人雷军再次将该消息宣布Python打造停车场车位智能识别Python打造停车场全部数据代码下载第1112章notebook课件。txt0。07kb第1617章notebook课件。txt0。07kb第27章notebook课件。txt0百度(Seo)快排之万能代理IP接口设计我们在python脚本百度(SEO)快排模拟点击最新核心源码中提到对快排影响的重要因素之一就是IP,如何使用多IP执行快排脚本有两种方法1使用动态拨号VPS2代理IP池今天我们主要Java是什么?Java是一门面向对象编程语言。他的两大特征功能强大简单易学。一Java语言特点1。简单性Java设计很像C,为了缩小语言和简单易学,设计者去掉了很多东西2。面对对象Java是一个Go1。17。5和Go1。16。12发布安全更新大家好,我是polarisxu。前些天刚发布1。17。4和1。16。11,今天又发布1。17。5和Go1。16。11,主要是安全更新,同样是小版本发布。这次发布,主要包含两个安全问品玩2021年度致敬系列发布,崔兴龙入选品玩12月10日讯,今日,以熔炼重铸为主题的TIC2021科技创新者大会在北京举办,大会特设品玩2021年度致敬专题系列,致敬技术原创与技术商业。崔兴龙以年度脑科学AI领军人物入选小米12,蓝思科技组装能力的重要试金石,客户与机型快速拓展可期12月28日,小米举行新品发布会,发布MIUI13系统后,小米正式发布了小米12系列手机。其实在这次发布会前,小米董事长雷军以及副总裁卢伟冰都表示,小米12将推出双尺寸版本,将在产失去华为后,台积电得到148亿美元订单,对华为的态度变了距离去年年底台积电正式对华为麒麟芯片停止代工,已经快过去一年。这一年华为因为缺芯手机业务受到了极大影响,华为手机市场份额直接从全球第二降为了其他一类而台积电这一年受到全球缺芯的影响新手做淘宝电商怎么做,做淘宝免费流量好还是付费流量好朋友们,你们好,我是小胖哥。接着吹上回的牛逼。在吹牛逼之前呢,麻烦朋友们用你们发财的小手给我点点关注,点点赞,点点转发。一见三年的朋友,可以获得我这边免费S出的一份学习大礼包,可以