我知道无法访问java中的变量链接(例如在& C或& php中)。但是,例如我有这样的任务:
public class JustTest {
private int n = 1;
private int x = 10;
public int[] getIntegers() {
return new int[] { n, x };
}
public void filledInteger() {
int[] vals = getIntegers();
System.out.println("Before change");
System.out.println(Arrays.toString(vals));
vals[0] = 2;
vals[1] = 20;
System.out.println("After change");
System.out.println(Arrays.toString(vals));
System.out.println("Values of name & xml");
System.out.println(n);
System.out.println(x);
System.out.println("calling getIntegers");
System.out.println(Arrays.toString(getIntegers()));
}
public static void main(String[] args) {
JustTest t = new JustTest();
t.filledInteger();
}
}
结果是:
Before change
[1, 10]
After change
[2, 20]
Values of name & xml
1
10
calling getIntegers
[1, 10]
所以,我想更改类实例的“n”和“x”字段的值。我不能通过直接设置(this-> n = 20;)来做到这一点,因为我可能不知道我有哪些字段。只有方法getIntegers知道。
(在这段代码中没有,但是例如我有子类有自己的字段,在父类中我有一个方法fillInteger(),它应该改变子类的指定属性(他从方法中知道这个属性) getIntegers,它在父类中是抽象的,并在子类中实现))
这是简单的实现(没有继承),使用php中的链接
<?php
class JustTest {
private $n = 1;
private $x = 10;
public function getIntegers() {
return array( &$this->n, &$this->x );
}
public function filledInteger() {
$vals = $this->getIntegers();
echo("Before change" . "<br/>");
echo(print_r($vals, true) . "<br/>");
$vals[0] = 2;
$vals[1] = 20;
echo("After change" . "<br/>");
echo(print_r($vals, true) . "<br/>");
echo("Values of n & x". "<br/>");
echo $this->n , "<br/>";
echo $this->x , "<br/>";
echo("call getIntegers again" . "<br/>");
echo(print_r($this->getIntegers(), true) . "<br/>");
}
}
$t = new JustTest();
$t->filledInteger();
?>
结果是:
Before change
Array ( [0] => 1 [1] => 10 )
After change
Array ( [0] => 2 [1] => 20 )
Values of n & x
2
20
call getIntegers again
Array ( [0] => 2 [1] => 20 )
这就是我真正需要的。我只是好奇我如何在java中实现它 希望你明白。
下一个例子:
public abstract class ParentTest {
abstract int[] getIntegers();
public void fillIntegers(int[] newIntegers) {
int[] integersOfChild = getIntegers();
for (int i = 0; i < integersOfChild.length; i++) {
integersOfChild[i] = newIntegers[i];
}
}
}
public class ChildTest extends ParentTest {
private int x;
private int y;
@Override
int[] getIntegers() {
return new int[] {x, y};
}
}
public class UseTest {
void main() {
List<ParentTest> list;
for (ParentTest item : list) {
item.fillIntegers(myItegers);
}
}
}
这就是我需要的。我有一个ParentTest实例列表(它可能是ChildTest,或ChildTest2,或ChildTest3;但它们是ParentTest的所有子项),我需要用我的整数值填充所有字段,但我不知道列表实例中是否有项目ChildTest,ChildTest2或ChildTest3类
答案 0 :(得分:1)
如何在Java中实现此功能?
通过Reflection API带来极大的痛苦。如果你想编写这样的代码,最好的想法是使用另一种语言。
考虑使用Groovy进行编程。您可以使用数组语法直接按名称访问类成员:t["n"] = 2;
这适用于旧版Java代码,因此无需修改TestClass以支持此用法。
答案 1 :(得分:1)
您所谈论的概念称为传递参考。 Java在很大程度上放弃了它 - 它产生了太多的副作用,就像你在这里看到的那样。
问题在于,虽然不幸的是你不能在这里做到这一点,但实际上它可以防止大量无意的错误被释放。
答案 2 :(得分:0)
这样的事情:
public final class JustTest {
private final Map<String, Object> fields;
public void filledInteger() {
System.out.println("Before change\n" + this.fields);
fields.put("N", 2);
fields.put("X", 20);
System.out.println("After change\n" + this.fields);
System.out.println("Values of name & xml\n" + fields.get("N")
+ "\n" + fields.get("X"));
}
private JustTest() {
this.fields = Maps.newHashMap(); // guava
fields.put("N", 1);
fields.put("X", 10);
}
public static void main(String[] args) {
final JustTest t = new JustTest();
t.filledInteger();
}
}
答案 3 :(得分:0)
你的php示例不会返回一个int数组,而是返回一个int指针数组。这不是你可以用Java做的事情,事实上,这不是你想用Java做的事情。给出一个用例,可能有更好的方法来解决你遇到的问题。
如果要返回其他人可以影响的对象并将其包含为成员变量,请执行此操作。一个ArrayList,HashMap等......有很多东西可以满足你的需求。如果给你一个别人的课程,你必须坚持自己的代码,你可以绕过他们的私人声明做以下事情:
public void setN(JustTest j, int n) {
//You would handle some exceptions here also
Field f = JustTest.class.getDeclaredField("n");
f.setInt(j, n);
}
答案 4 :(得分:0)
如果没有反射,您不能执行单个字段,但可以更改集合的内容。请注意,这不是真正意图的行为,而是在使用集合时必须注意的事项。
输出5 3 2 4 2 4
public class Test
{
public Vector<Integer> args = new Vector<Integer>();
public void fillArgs()
{
args.add(5);
args.add(3);
}
public Vector<Integer> getArgs()
{
return args;
}
public static void main(String args[])
{
Test s = new Test();
s.fillArgs();
Vector<Integer> temp = s.getArgs();
for (Integer i : temp)
System.out.println(i);
temp.setElementAt(2, 0);
temp.setElementAt(4, 1);
for (Integer i : temp)
System.out.println(i);
for (Integer i : s.getArgs())
System.out.println(i);
}
}