2009-11-17 65 views
4

很抱歉,如果这听起来像一个新手的问​​题,但有一天,一个Java开发者关于通过引用传递一个放慢参数(通过其被换货只是传递一个参考对象)你可以在Java中通过引用传递吗?

从C#角度来看,我可以通过一个参考提到按值或通过引用类型,这也是值类型

我写了一个noddie控制台应用程序来显示我的意思..我可以在Java中做到这一点?

namespace ByRefByVal 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      //Creating of the object 
      Person p1 = new Person(); 
      p1.Name = "Dave"; 
      PrintIfObjectIsNull(p1); //should not be null 

      //A copy of the Reference is made and sent to the method 
      PrintUserNameByValue(p1); 
      PrintIfObjectIsNull(p1); 

      //the actual reference is passed to the method 
      PrintUserNameByRef(ref p1); //<-- I know im passing the Reference 
      PrintIfObjectIsNull(p1); 

      Console.ReadLine(); 
     } 

     private static void PrintIfObjectIsNull(Object o) 
     { 
      if (o == null) 
      { 
       Console.WriteLine("object is null"); 
      } 
      else 
      { 
       Console.WriteLine("object still references something"); 
      } 
     } 

     /// <summary> 
     /// this takes in a Reference type of Person, by value 
     /// </summary> 
     /// <param name="person"></param> 
     private static void PrintUserNameByValue(Person person) 
     { 
      Console.WriteLine(person.Name); 
      person = null; //<- this cannot affect the orginal reference, as it was passed in by value. 
     } 

     /// <summary> 
     /// this takes in a Reference type of Person, by reference 
     /// </summary> 
     /// <param name="person"></param> 
     private static void PrintUserNameByRef(ref Person person) 
     { 
      Console.WriteLine(person.Name); 
      person = null; //this has access to the orginonal reference, allowing us to alter it, either make it point to a different object or to nothing. 
     } 


    } 

    class Person 
    { 
     public string Name { get; set; } 
    } 
} 

如果它不能做到这一点,那么它只是通过值传递引用类型? (是公平地说)

非常感谢

骨头

+0

无尽的C#区别甚至不存在于Java中。 Java中的“引用类型”是什么?非原始类型?你不能按值传递非原始类型 - 它们总是引用。由于这些概念并没有真正在语言之间进行映射,所以您究竟在问什么? – 2009-11-17 12:22:35

+4

您当然可以按值传递非原始类型。事实上,这就是所有的Java。 Java中的所有东西都是原语和引用,并且都是按值传递的。 – 2009-11-17 12:23:57

+0

从你的例子中,我真的很高兴Java不支持这个。这会打开Java中不会发生的各种问题。 – 2009-11-17 20:06:29

回答

31

没有,爪哇不能做到这一点。 Java只能通过价值传递。它也通过值传递引用。

+14

+1对于“它通过值传递引用”。 “这里最精确的东西。 – NawaMan 2009-11-17 12:33:14

+0

+1谢谢!如果我可以这样说,我现在只是在业余时间用Eclipse学习JAVA几天。这是你在这里说的重要的语言特征。 – 2010-04-29 13:17:09

10

传递引用是Java开发人员经常误解的概念,可能是因为他们无法做到这一点。阅读:

http://javadude.com/articles/passbyvalue.htm

+0

我们如何在java中实现swap功能。 – 2009-11-17 13:04:04

+0

交换无法在java中实现,因为所有参数总是按值传递。如果你想交换两个值,你必须在你的方法范围内进行;你将无法重构它自己的方法。像JRL这样的解决方法可能是可能的,但并不是真正做你想做的,这里 – 2009-11-17 13:13:10

0

的价值是的,正如你所指出,Java正在传递引用。这对于java程序员来说是一个很好的采访主题,大多数人似乎认为它错了。

1

从C#角度来看,我可以按值传递一个 引用类型或 参考,这也是千真万确的重视 类型

这是比较误导说“按值传递引用类型“在C#中。

不能按值传递引用类型 - 你可以传递一个参考对象参考参考。在java中,你不能传递参考。

但是,您的noddie应用程序使得区别更清晰一些。

+0

我同意你的偏见 – dbones 2016-12-06 21:01:12

0

您可以做的最接近的是通过AtomicReference。这可以被调用者改变。这是相当丑陋的,但恕我直言,它应该是。改变方法中的参数是个不错的主意。

1

从技术上讲,我们知道,引用对象的变量只是指向对象的指针。将对象作为参数传递给方法时,指针或引用将被复制到参数变量中。 Java将此称为“按值传递”。

所以,你最终会得到至少两个引用同一个对象的变量。如果将参数变量设置为null,则其他变量由于引用计数而保持其值。

如果您有以下方法:

public void function(Person person) {}; 

和对象:

Person marcus = new Person(); 
marcus.name = "Marcus"; 

调用这样的方法:

function(marcus); 

你基本上是在方法的局部得到这个适用范围:

Person person = marcus; 

如果您设置了person = null,它不会影响marcus的值。这是由于参考计数。

但是,如果你这样做:

person.name = null; 

也是如此:

marcus.name == null; 

你确实有在参数变量对原始对象的引用。影响参数变量确实会影响原始对象。你可以做任何事情,除了将其设置为空并且期望原始设置也为空。引用计数可以防止这一点