【问题标题】:Java reflection to change parameter?Java反射改变参数?
【发布时间】:2013-01-15 02:11:11
【问题描述】:

我正在用 Java 编写一个方法,我想模​​拟引用。由于 java 没有 C# 中的 out 关键字,也没有 C++ 中的引用/指针,我想知道我是否可以使用反射来模拟它。

一个例子是:

public static boolean ChangeValue(Object Input, Object Output) {
    //Use some reflection here to change the value of Output?
    return true;
}

然后在主目录中:

public static void main(String[] args) {
    int I = 0;
    ChangeValue(I, I);
    System.out.println(I);
}

所以.. 我可以使用反射来更改传递给我的 ChangeValue 方法的任何参数的值吗?我不想返回 Composite 对象..

【问题讨论】:

  • 如果你坚持使用这种模式,你最好实现一个简单的Out<T>容器类。
  • ^是的,它确实可以编译。你可以试试看。对象是一个多态类。任何东西都可以作为对象传递,包括原语。
  • 你说得对,我的立场是正确的。

标签: java reference out ref


【解决方案1】:

Java 是按引用值传递的,这意味着如果您将一个对象传递给一个方法并对其进行修改,那么该方法“外部”的对象也将被修改(因为该对象只是一个引用)。这方面的一个例子是在数组上调用Arrays.sort

但是,对于原语(如int),情况并非如此,在这种情况下,Java 是按值传递的,因此您使用int I 的示例将不起作用。要修改int I 的值,您应该从您的方法中返回一个int,并相应地将其设置为I

这意味着为了从ChangeValue 方法中修改对象的值,不需要反射;对方法内的对象所做的任何操作,实际上都会修改main 方法范围内的对象。

【讨论】:

  • :S 我尝试传递 Integer 并更改值。它不会影响 main 中的任何内容。
  • @CantChooseUsernames 正确,此答案中没有任何内容暗示它会这样做。
  • @CantChooseUsernames 在我回答的第二段中,我解释了原语(如int)如何不是通过引用值传递的。相反,您应该返回一个值并将其设置为 I(正如我的回答所解释的那样)。
  • "在方法内对对象所做的任何事情,都会有效地修改主方法范围内的对象。"我认为读错了。 Integer 是一个类,int 是一个原始类型。
  • “对象”是那里的关键词;否则,您阅读正确。基元(intlongdoublecharboolean 等)不是对象,而是通过值而不是引用值传递。
【解决方案2】:

不,你不能。

您可以更改传递给方法的对象的属性,但不能更改调用代码的参数引用的内容——只能更改其引用的属性。

【讨论】:

  • @CantChooseUsernames 我是说你不能;您不能从被调用的方法更改调用代码引用的内容,只能更改它引用的内容的属性。与 int 相同;您不能在调用代码中更改变量的值。
【解决方案3】:
    public static boolean changeValue(ArrayList<String> input, ArrayList<String> output) {
        //this changes a property on output, but does not change the reference to output
        output.addAll(input);


        return true;
    }


    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<String>();
        ArrayList<String> list2 = new ArrayList<String>();

        list1.add("Foo");

        System.out.println("List 2: " + list2);
        System.out.println("List 2 size:" + list2.size());

        changeValue(list1, list2);

        System.out.println("List 2: " + list2);    
        System.out.println("List 2 size:" + list2.size());
    }

将打印...

列表 2:ArrayList@0x23409

列表 2 大小:0

列表 2:ArrayList@0x23409

列表 2 大小:1

【讨论】:

  • +1 我喜欢这个。我将放弃并使用类型创建一个类并对其进行修改:(真的希望有一种方法可以在没有变通的情况下做到这一点..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 2012-06-25
  • 1970-01-01
相关资源
最近更新 更多