【问题标题】:Java pass-by-value workaround for object properties对象属性的 Java 值传递解决方法
【发布时间】:2012-08-20 16:58:46
【问题描述】:

在我的Java源代码的一种方法中,同一块代码出现了很多次:

<some code>
<some code>
<block of code>
<some code>
<block of code>
<some code>
<some code>
<some code>
<block of code>
<some code>
<some code>
<block of code>
<some code>
etc..

这段代码的作用是找出对象的哪个属性应该是代码的目标。更具体地说,在块的开头我们有一个字符串“Object.property”,代码的任务是解析它,以便找出“Object”是什么类型的对象,以及“Object”的什么属性” “财产”是。当这完成并且块结束时,执行继续对所述对象的所述属性做一些事情。该属性可以用于比较,或者可以为其分配一些东西。

现在,我的问题是我想通过将此块放在另一个方法中来稍微整理一下代码,然后我可以多次调用该方法。此外,如果我在这个块中发现了一个错误,我不需要通过每一次出现来修复它 - 只需一种方法。

所以这基本上就是我想做的:

<some code>
<some code>
property = parse();
<some code>
property = parse();
<some code>
<some code>
<some code>
property = parse();
<some code>
<some code>
property = parse();
<some code>
etc..

property parse(){
 <block of code>
 return property;
}

现在,由于 Java 没有任何指针,我无法从这个新方法返回一个整数属性。将返回该整数的副本(按值传递),我的所有其余代码将处理的是属性的本地整数副本,而不是属性本身。如果该属性仅用于比较,这当然很好,但是当我的其余代码想要为它分配一些东西时,事情就不再起作用了。

是否有一种聪明而简单的解决方法,以便我可以缩短我的 Java 代码,并且在修改它时,我只需要修改代码的一部分?

编辑:

为了给你一些真实的代码,代码块可能看起来像这样,当它没有放在不同的方法中时,它得到一个名为 toParse 的字符串(对于这个例子来说,它可能是“niceShirt.size”) :

String[] parts = toParse.split('\\.');
if(pantsList.containsKey(parts[0])){
    if(parts[1] == "size") pantsList.get(parts[0]).size += 1;
    if(parts[1] == "daysWorn") pantsList.get(parts[0]).daysWorn += 1;
}
if(shirtsList.containsKey(parts[0])){
    if(parts[1] == "size") shirtsList.get(parts[0]).size += 1;
    if(parts[1] == "daysWorn") shirtsList.get(parts[0]).daysWorn += 1;
}
if(shoesList.containsKey(parts[0])){
    if(parts[1] == "size") shoesList.get(parts[0]).size += 1;
    if(parts[1] == "daysWorn") shoesList.get(parts[0]).daysWorn += 1;
}

现在这样的代码多次出现,我很想有一个这样的方法:

String[] parts = toParse.split('\\.');
if(pantsList.containsKey(parts[0])){
    if(parts[1] == "size") return pantsList.get(parts[0]).size;
    if(parts[1] == "daysWorn") return pantsList.get(parts[0]).daysWorn;
}
if(shirtsList.containsKey(parts[0])){
    if(parts[1] == "size") return shirtsList.get(parts[0]).size;
    if(parts[1] == "daysWorn") return shirtsList.get(parts[0]).daysWorn;
}
if(shoesList.containsKey(parts[0])){
    if(parts[1] == "size") return shoesList.get(parts[0]).size;
    if(parts[1] == "daysWorn") return shoesList.get(parts[0]).daysWorn;
}

而我在其余代码中需要做的就是:

parse(toParse) += 1;

..但这不起作用,因为 parse(toParse) 现在是一个副本,一个按值返回,所以它不会对对象的真实属性做任何事情。

我希望这有助于澄清问题?

【问题讨论】:

  • 请给我们一些真实代码!
  • 您可以返回一个Property 对象(即在Property 类中定义),例如,它有一个value 字段,您可以为其提供一个setter。
  • 哦,你能做到吗?很好,我从来没想过。谢谢!
  • 您能否再给我们一些代码示例。也许您可以为此使用 groovy,但这取决于您将向我们展示什么。

标签: java pass-by-reference pass-by-value return-by-reference return-by-value


【解决方案1】:

您可以将 getter 和 setter 包装在实现简单接口的匿名类的对象中:

interface PropertyInfo {
    Object get();
    void set(Object value);
}

parse() 方法将根据调用者传入的其他数据返回此接口的实现,该实现知道如何进行 get 并知道如何进行 set 操作:

private PropertyInfo parse(...) { // take some parameters
    // Find your getter and setter through reflection
    final Method getter = ...
    final Method setter = ...
    return new PropertyInfo() {
        public Object get() {
            // Use the getter
        }
        public void set(Object value) {
            // Use the setter
        }
    };
}

当你需要在某个条件下使用属性时,你会使用这样的东西:

PropertyInfo p = parse(...); // pass whatever needs to be parsed
if (p.get() == 123) ...

当你需要设置属性时,你可以这样调用它:

PropertyInfo p = parse(...); // pass whatever needs to be parsed
p.set(123);

【讨论】:

  • 这看起来很棒!我永远无法独自解决这个问题!如果我能得到这个工作,我会去试试,非常感谢你!
【解决方案2】:

使您的方法无效并让第一个参数成为“句柄”对象 - 一个具有整数字段的简单对象。该对象将按值传递,但它的值可以随意修改。

【讨论】:

    猜你喜欢
    • 2017-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2013-12-28
    • 2015-08-18
    相关资源
    最近更新 更多