1.0建立二叉树的代码,在java中必须创建二叉树的方法必须用返回值,因为不存在c语言中的引用传递,在java中只有值传递 代码1为正确,代码2(没有使用返回值)为错误。那么为什么之前的例子中将对象作为参数时,对对象内容的更改还是正确的,也没有使用返回值,二者看似矛盾,其实并不矛盾,以前都没有理解到这个本质,本质就是参数中,确实是有一个临时变量,交换形式对象参数,实际的参数不会改变,但是改变形式参数的引用所指向的内容,即这个对象本身改变,其实参所引用的对象也是同一个对象,当然该对象也会发生变化,因为实参和形参引用的都是同一个对象,只不过是两份地址的拷贝。

即便是c语言如果不用引用传递-&,就是说用指针,也需要用返回值的方法建立二叉树,才能将已建立好的二叉树头指针返回给打印函数的参数。当然java中可以采用对私有变量等操作,即不不使用参数传递,而仅仅是创建函数和打印函数共同操作的是同一个变量也可以吧,估计递归就不好用了,这个怎么做没去想!~~~

错误代码:这个时候打印出来的树的节点为空,printInOrder(tree1)输出节点为空:

View Code

import java.util.*;

class TNode{

int data;

TNode lchild;

TNode rchild;

TNode(int a)

{

data=a;

lchild=null;

rchild=null;

}

}

public class BTree {

static TNode root=new TNode(1);

static void creatTree(TNode root)

{

Scanner in=new Scanner(System.in);

int a=in.nextInt();

if(a==0){

root=null;

return;

}

else{

root=new TNode(a);

creatTree(root.lchild);

creatTree(root.rchild);

}

}

static void printInOrder(TNode root){

if(root==null)

return;

else{

System.out.print(root.data);

printInOrder(root.lchild);

printInOrder(root.rchild);

}

}

public static void main(String[] args) {

//TODO Auto-generated method stub

creatTree(root);

printInOrder(root);

}

}

正确代码:

View Code

import java.util.Scanner;

class Tode{

int data;

Tode lchild;

Tode rchild;

Tode(int a)

{

data=a;

lchild=null;

rchild=null;

}

}

public class TREE{

static Tode root=null;

static Tode creatTree(Tode root)

{

Scanner in=new Scanner(System.in);

int a=in.nextInt();

if(a==0){

return null ;

}

else{

root=new Tode(a);

root.lchild=creatTree(root.lchild);

root.rchild=creatTree(root.rchild);

return root;

}

}

static void printInOrder(Tode root){

if(root==null)

return;

else{

System.out.print(root.data);

printInOrder(root.lchild);

printInOrder(root.rchild);

}

}

public static void main(String[] args) {

//TODO Auto-generated method stub

Tode tree1=creatTree(root);

printInOrder(tree1);

}

}

1.1、疑惑解决了,原来认为方法中传入一个对象的话(数组也行),如果方法内部对这个对象的内部参数进行了更改,则其实就是对外部的这个静态对象也进行了修改,相当于c++中的真正的引用传递吧,但是传入的是整型等普通类型,则还是不能够更改,可以见下面的实例。如果传入的对象是数组的话,也可以更改,因为java中数组也是对象~,其实也不是 因为是对引用所指向的内容进行了修改,引用可以有多个,但是引用所指向的内容只有一份!!!!!!

以下程序的输出结果是012

View Code

import java.util.*;

class node{

int data;

node lchild;

node rchild;

public node(int a){

data=a;

lchild=null;

rchild=null;

}

}

public class testclass2 {

public void changeroot(node root){

node newnode1=new node(1);

node newnode2=new node(2);

root.lchild=newnode1;

root.rchild=newnode2;

}

public void print(node root){

System.out.println(root.data);

System.out.print(root.lchild.data);

System.out.print(root.rchild.data);

}

public static void main(String[] args){

node root=new node(0);

testclass2 dd=new testclass2();

dd.changeroot(root);

dd.print(root);

}

}

1.2、下面是另一个例子,在算法例子中也常用到因为是 对引用所指向的内容进行了修改,引用可以有多个,但是引用所指向的内容只有一份!!!!!!

以下程序输出结果是2 4 3 4

View Code

void diguiInorderTraverse(node root){

root.lchild

}

解释说的通了,传入root,对root修改,其实就相当于

class A{

int b=2;

}

public class Testclass {

static A a=new A();

static void changeA(A a){

a.b=3;

}

static int b=4;

static void changeB(int b){

b=5;

}

public static void main(String[] args) {

//TODO Auto-generated method stub System.out.println(a.b);

System.out.println(b);

changeA(a);

changeB(b);

System.out.println(a.b);

System.out.println(b);

}

}

1.3、也就是说root对象确实分配了一个临时对象,传入的都是地址的引用,所以对这个参数的改变,对引用所指向的内容进行了修改,引用可以有多个,但是引用所指向的内容只有一份!!!!!!

我看了一些引用调用和值调用的定义,很多人都把是传递值,还是传递地址?是改变参数自身内容,还是改变参数所指向的地址中的内容作为区别这两种调用的标志。这很不恰当,这些说法很容易让我们联想到Java的对象参数传递是引用调用,实际上,Java的对象传递仍然是值调用。

引用调用:在参数传递的过程中,形参并不是实参的副本,而是实参本身。这种调用实参和形参在内存中实际上都是同样的一个区域,只是这个区域的表示(参数名)不同而已。

值调用:在参数传递过程中,创建了一个实参的副本——形参。形参和实参在内存中是两个完全不同的区域。因此形参内容的改变并不能影响到实参。

方法调用(call by)是一个标准的计算机科学术语。方法调用根据参数传递的情况又分为值调用(call by reference)和引用调用(call by value)。江湖上有很多关于这两种调用的定义,最通常的说法是传递值的是值调用,传递地址的是引用调用。这其实很不恰当,这种这些说法很容易让我们联想到Java的对象参数传递是引用调用,实际上,Java的对象参数传递仍然是值调用。

以下摘自该段落:

Java代码

1.publicclassEmployee {

2.

3.publicString name=null;

4.

5.publicEmployee(String n){

6.this.name=n;

7.}

8.//将两个Employee对象交换

9.publicstaticvoidswap(Employee e1,Employee e2){

10.Employee temp=e1;

11.e1=e2;

12.e2=temp;

13.System.out.println(e1.name+" "+e2.name);//打印结果:李四张三

14.}

15.//主函数

16.publicstaticvoidmain(String[] args) {

17.Employee worker=newEmployee("张三");

18.Employee manager=newEmployee("李四");

19.swap(worker,manager);

20.System.out.println(worker.name+" "+manager.name);//打印结果仍然是:张三李四

21.}

22.}

上面的结果让人很失望,虽然形参对象e1,e2的内容交换了,但实参对象worker,manager并没有互换内容。这里面最重要的原因就在于形参e1,e2是实参worker,manager的地址拷贝。

大家都知道,在Java中对象变量名实际上代表的是对象在堆中的地址(专业术语叫做对象引用)。在Java方法调用的时候,参数传递的是对象的引用。重要的是,形参和实参所占的内存地址并不一样,形参中的内容只是实参中存储的对象引用的一份拷贝。

如果大家对JVM内存管理中Java栈的局部变量区有所了解的话(可以参见《》),就很好理解上面这句话。在JVM运行上面的程序时,运行main方法和swap方法,会在Java栈中先后push两个叫做栈帧的内存空间。main栈帧中有一块叫局部变量区的内存用来存储实参对象worker和manager的引用。而swap栈帧中的局部变量区则存储了形参对象e1和e2的引用。虽然e1和e2的引用值分别与worker和manager相同,但是它们占用了不同的内存空间。当e1和e2的引用发生交换时,下面的图很清晰的看出完全不会影响worker和manager的引用值。

Java对象参数传递虽然传递的是地址(引用),但仍然是值调用。是时候需要给引用调用和值调用一个准确的定义了。

值调用(call by value):在参数传递过程中,形参和实参占用了两个完全不同的内存空间。形参所存储的内容是实参存储内容的一份拷贝。实际上,Java对象的传递就符合这个定义,只不过形参和实参所储存的内容并不是常规意义上的变量值,而是变量的地址。咳,回过头想想:变量的地址不也是一种值吗!

引用调用(call by reference):在参数传递的过程中,形参和实参完全是同一块内存空间,两者不分彼此。实际上,形参名和实参名只是编程中的不同符号,在程序运行过程中,内存中存储的空间才是最重要的。不同的变量名并不能说明占用的内存存储空间不同。

大体上说,两种调用的根本并不在于传递的是值还是地址(毕竟地址也是一个值),而是在于形参和实参是否占用同一块内存空间。事实上,C/C++的指针参数传递也是值调用,不信试试下面的C代码吧!

C代码

1.#include

2.voidswap(int*a1,int*b1){

3.int*t=a1;

4.a1=b1;

5.b1=t;

6.}

7.intmain(){

8.intx1=100;

9.intx2=200;

10.int*a=&x1;

11.int*b=&x2;

12.printf("%d %d\n",*a,*b);

13.swap(a,b);

14.printf("%d %d\n",*a,*b);

15.return0;

16.}

但C/C++是有引用调用的,这就是C/C++一种叫做引用的变量声明方法:int a; int &ra=a;其中ra是a的别名,两者在内存中没有区别,占用了同一个内存空间。而通过引用(别名)的参数传递就符合引用调用的特点了。大家可以去试试

void swap(int &a1,int &b1);的运行结果。

java中形参不可以是对象吗_(重要)java都是值传递,与对象形参所指向的对象改变,其实参所指向的对象也相应改变并不矛盾(2011年9.30日一天写的两个程序的总结结果)...相关推荐

  1. (重要)java都是值传递,与对象形参所指向的对象改变,其实参所指向的对象也相应改变并不矛盾(2011年9.30日一天写的两个程序的总结结果)...

    1.0建立二叉树的代码,在java中必须创建二叉树的方法必须用返回值,因为不存在c语言中的引用传递,在java中只有值传递 代码1为正确,代码2(没有使用返回值)为错误.那么为什么之前的例子中将对象作 ...

  2. Java main方法_解释Java中的main方法,及其作用_一个java文件中可包含多个main方法

    public static void main(String[] args) {} 或者 public static void main(String args[]) {} main方法是我们学习Ja ...

  3. JAVA中为什么要用接口定义编程_【Java公开课|为什么要用Java接口,这些内容你一定要搞清楚】- 环球网校...

    [摘要]作为一门面向对象编程语言,Java吸收了C++语言的优点,也展现了其强大的一面,我们能在各个地方看到其功能强大和简单易用的两个特征,当然,也吸引了很多程序员的注意力,所以就有人想了解Java的 ...

  4. 以下关于java中布局管理说法错误的是_对于 Java 中的布局管理器,以下说法中错误的是( )。_2019复习答案_学小易找答案...

    [单选题]下列哪个酶与丙酮酸生成糖无关? [单选题]宋代( )的产地是当时的福建建安. [单选题]建筑平面图中,外部尺寸一般标注( )尺寸. [单选题]MCS - 51 单片机的 CPU 主要的组成部 ...

  5. java中dao和实体类的关系_【JAVA基础】 PO、VO、BO、DTO、POJO、DAO之间的关系详解...

    J2EE开发中大量的专业缩略语很是让人迷惑,尤其是跟一些高手讨论问题的时候,三分钟就被人家满口的专业术语喷晕了,PO VO BO DTO POJO DAO,一大堆的就来了 首先声明偶也不是什么高手,以 ...

  6. java中怎么调用邮箱自动回信息_使用java发送短信和邮件

    (1)发送短信 1.1在中国网建SMS上注册一个用户名,并获取短信密钥(非登录密码) 1.2代码 import java.io.IOException; import org.apache.commo ...

  7. java中怎么下载图片不显示图片_关于Java/Kotlin下载图片,图片打开不能显示问题探究...

    图片下载其实是个很简单的功能,通过IO流从在线地址获取流,之后将流输出到文件即可完成下载功能,但是,最近我发现某个网站中的图片下载成功,但是打开却是无法打开,这让我迷惑,百度上根本就没有人说清楚 今天 ...

  8. java中实现接口采用的关键字是_一个Java类实现一个接口使用的是implements关键字。...

    个用务人为是导致的债的行销权可能债权人行使撤. 无关调制信号它与及电方式速率,类实务的新业宽带也是引入方便手段,在网展中络发,想的扩容是理手段. 个接s关标志牌的要求水线设置. 的受定期通信预算资格建 ...

  9. java中的後綴表達式_求Java堆栈,将中缀算术表达式转换成后缀表达式。

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package lab2.lang; import java.util.ArrayList; import java.util.HashMap; impo ...

最新文章

  1. 什么是以太坊?它到底怎么运作的?
  2. 【冰极峰教程系列之二】:牢不可破的九宫格布局
  3. GridView编辑删除操作
  4. 首届剑桥国际青年学术论坛开幕 第四范式携手DeepMind、华为共话AI技术革新
  5. 64位cad commondialog添加_常用软件分享PDF转CAD软件
  6. MySQL-04:数据内容操作-增删改查-基本命令笔记
  7. linux子系统安装gromacs,科学网—Windows下GROMACS程序的编译 - 李继存的博文
  8. 星巴克“猫爪杯”遭国人疯抢 而 “大白兔冰淇淋”在美国大火
  9. 查漏补缺!java主要包括哪几种开发平台
  10. jQuery入门[1]-构造函数
  11. 制作PPT的常用网站及一些基本原则
  12. pano2vr导出html看不,【答疑】pano2vr6导出的全景,是空白的,打不开,? - 视频教程线上学...
  13. 民商法领域的论文选题求推荐?
  14. 笔记本电脑系统迁移0xc0000225
  15. unity中VideoPlayer播放视频,使用Shader除去黑底且无黑边
  16. android状态栏右上角增加图标的方法
  17. 暴跌27%!科通芯城遭沽空机构狙击 被指“横跨十年的世纪骗案”
  18. 【云原生|Docker系列6】Docker Compose的命令使用详解
  19. MySQL 数据类型(转)
  20. Attempted to read or write protected memory. This is often an indication that other memory is corrup

热门文章

  1. NTU 课程笔记:CV6422 置信区间
  2. pytorch 笔记: 复现论文 Stochastic Weight Completion for Road Networks using Graph Convolutional Networks
  3. 强化学习(六)时序差分在线控制算法SARSA
  4. hadoop学习--多表关联
  5. Matlab读取avi视频并播放
  6. Anaconda安装jieba方法
  7. Python编程基础:第十九节 索引Index Operator
  8. HBase在阿里搜索中的应用实践
  9. 体系化认识RPC--转
  10. HDFS 原理、架构与特性介绍--转载