public void setNext(Node next) { this.next=next; } public Node getNext() { return next; }
public String toString() { return "data:"+data; } }
您好,我的调用add的时候都是调用 link a = new link();a.add(a.root,1),把add里面节点名命名为root可能误导您了,其实他就是个局部变量罢了,我在逻辑上也没有把他当成root 我传递a.root进add,它到底是值传递还是引用传递呢?
您好,我的调用add的时候都是调用 link a = new link();a.add(a.root,1),把add里面节点名命名为root可能误导您了,其实他就是个局部变量罢了,我在逻辑上也没有把他当成root 我传递a.root进add,它到底是值传递还是引用传递呢? 当然是传值!只不过在这里,这个值实际上是你在堆上创建的那个node对象的地址!!!你知道他是局部变量就好啦,你给调用方法传递参数时,是实参的值传递给形参,这里的实参是a.root,形参是add方法参数中root;当你调用add方法时,会在方法内部创建局部变量root,然后将实参a.root的值(即地址值)复制给root,然后你才能在方法中通过root访问堆上那个node对象!说到底,java中方法参数传递本质都是按值传递(我表达能力不强,你可以找本书看看关于方法参数传递的章节) 比如: Object a=new Object();//这里的a是引用类型的变量,它本身是在栈上创建的,但它保存的值是在堆上创建出来的那个Object的地址
我修改了你的代码,并加了注释,请在本地测试 package com.liandy.test;public class Test { class node// 节点类 { int data; node next; node(int d) { data = d; } } node root;// 链表头 public void add(node root, int data)// 添加节点 { if (root == null) { root = new node(data); this.root = root; // 这个局部变量root在运行完就释放了,如果不加这句,并不会赋值给全局变量root, //所以全局root还是null,并不是引用还是值的问题,是变量作用域的问题 } else { add(root.next, data); } }
public static void main(String[] args) { Test a = new Test(); a.add(a.root,1); System.err.println(a.root.data); } }
Java 说的引用其实更像 C 的指针。大师们都说 Java 都是值传递。抽象类型的参数在传递时的效果跟使用指针是一样的。 另外你可能也注意到了 Java 中的抽象类型,在创建实例时都要 new 一下,这不就是 C 指针做的事情么。
给个单向链表例子给你参考下:
package lesson3;public class Demo4
{
public static void main(String[] args)
{
Link link=new Link();
for(int i=0;i<10;++i)
{
link.add(new Node(i));
}
link.printLink();
}
}class Link
{
private Node rootNode; // 链表头
private Node curNode;
public void add(Node node)// 添加节点
{
if(rootNode==null)
{
rootNode=node;
curNode=rootNode;
}
else
{
curNode.setNext(node);
curNode=node; //保存当前节点
}
}
public void printLink()
{
Node tempNode=rootNode;
while(tempNode!=null)
{
System.out.println(tempNode);
tempNode=tempNode.getNext();
}
}
}class Node// 节点类
{
private int data;
private Node next;
public Node(int d)
{
data = d;
next=null;
}
public void setNext(Node next)
{
this.next=next;
}
public Node getNext()
{
return next;
}
public String toString()
{
return "data:"+data;
}
}
您好,我的调用add的时候都是调用 link a = new link();a.add(a.root,1),把add里面节点名命名为root可能误导您了,其实他就是个局部变量罢了,我在逻辑上也没有把他当成root
我传递a.root进add,它到底是值传递还是引用传递呢?
您好,我的调用add的时候都是调用 link a = new link();a.add(a.root,1),把add里面节点名命名为root可能误导您了,其实他就是个局部变量罢了,我在逻辑上也没有把他当成root
我传递a.root进add,它到底是值传递还是引用传递呢?
当然是传值!只不过在这里,这个值实际上是你在堆上创建的那个node对象的地址!!!你知道他是局部变量就好啦,你给调用方法传递参数时,是实参的值传递给形参,这里的实参是a.root,形参是add方法参数中root;当你调用add方法时,会在方法内部创建局部变量root,然后将实参a.root的值(即地址值)复制给root,然后你才能在方法中通过root访问堆上那个node对象!说到底,java中方法参数传递本质都是按值传递(我表达能力不强,你可以找本书看看关于方法参数传递的章节)
比如:
Object a=new Object();//这里的a是引用类型的变量,它本身是在栈上创建的,但它保存的值是在堆上创建出来的那个Object的地址
package com.liandy.test;public class Test {
class node// 节点类
{
int data;
node next; node(int d) {
data = d;
}
} node root;// 链表头 public void add(node root, int data)// 添加节点
{
if (root == null) {
root = new node(data);
this.root = root; // 这个局部变量root在运行完就释放了,如果不加这句,并不会赋值给全局变量root,
//所以全局root还是null,并不是引用还是值的问题,是变量作用域的问题
} else {
add(root.next, data);
}
}
public static void main(String[] args) {
Test a = new Test();
a.add(a.root,1);
System.err.println(a.root.data);
}
}
另外你可能也注意到了 Java 中的抽象类型,在创建实例时都要 new 一下,这不就是 C 指针做的事情么。