你能通过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"); } } /// /// this takes in a Reference type of Person, by value /// /// 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. } /// /// this takes in a Reference type of Person, by reference /// /// 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; } } }
如果java不能这样做,那么它只是按值传递引用类型? (这是公平的说法)
非常感谢
骨头
不,Java不能这样做。 Java只按值传递。 它也通过值传递引用。
通过引用传递是一个经常被Java开发人员误解的概念,可能是因为他们不能这样做。 读这个:
从C#的角度来看,我可以通过值或引用传递引用类型,这也适用于值类型
在C#中说“按值传递引用类型”是相对误导的。
您不能按值传递引用类型 – 您可以传递对象的引用或对引用的引用 。 在java中,您无法传递对引用的引用。
然而,你的noddie应用程序使区别更加清晰。
从技术上讲,正如我们所知,引用对象的变量是对象的严格指针。 将对象作为参数传递给方法时,指针或引用将复制到参数变量。 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;
您确实在参数变量中引用了原始对象。 影响参数变量会影响原始对象。 您可以执行除将其设置为null之外的所有操作,并期望将原始设置为null。 引用计数可防止这种情
是的,正如您所指出的,Java正在按值传递引用。 这为java程序员提供了一个很好的面试主题,大多数人似乎都错了。
您可以做的最接近的是通过AtomicReference。 这可以由呼叫者改变。 这是相当丑陋,但恕我直言应该是。 更改方法中的参数是个坏主意。