关于java和链接的有趣问题&&引用;
我知道在java中没有访问变量链接的方法(比如in&C或&php)。但例如,我有这样的任务:关于java和链接的有趣问题&&引用;,java,pass-by-reference,Java,Pass By Reference,我知道在java中没有访问变量链接的方法(比如in&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 =
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]
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 )
所以,我想更改类实例的“n”和“x”字段的值。我不能直接设置(this->n=20;),因为我可能不知道我有哪些字段。只有getIntegers方法知道
(在这段代码中没有,但例如,我有一个具有自己字段的子类,在父类中我有一个filledInteger()方法,该方法应该更改子类的指定属性(他从方法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();
?>
这正是我所需要的。我只是好奇我该如何在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{
抽象int[]getIntegers();
public void fillIntegers(int[]newIntegers){
int[]integersOfChild=getIntegers();
for(int i=0;i
这就是我需要的。我有一个ParentTest实例列表(可能是ChildTest、ChildTest2或ChildTest3;但它们都是ParentTest的子项),我需要用整数值填充所有字段,但我不知道列表中的项是ChildTest、ChildTest2还是ChildTest3类的实例
如何在Java中实现这一点
通过反射API带来巨大的痛苦。如果您想编写这样的代码,最好使用另一种语言
考虑改用Groovy编程。您可以使用数组语法通过名称直接访问类成员:
t[“n”]=2代码>这适用于遗留Java代码,因此无需修改TestClass来支持此用法。您所讨论的概念称为按引用传递。Java在很大程度上已经放弃了它——它产生了太多的副作用,就像您在这里看到的那样
问题是,虽然不幸的是,您不能在这里这样做,但它实际上阻止了大量无意中释放的bug。这样的事情怎么样:
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();
}
}
公共期末考试{
私有最终地图字段;
公共空白填充整数(){
System.out.println(“更改前\n”+此.fields);
字段。放置(“N”,2);
字段。放置(“X”,20);
System.out.println(“更改后\n”+此.fields);
System.out.println(“name和xml的值”+fields.get(“n”)
+“\n”+字段。获取(“X”);
}
私人测试(){
this.fields=Maps.newHashMap();//番石榴
字段。放置(“N”,1);
字段。放置(“X”,10);
}
公共静态void main(字符串[]args){
最终JustTest t=新的JustTest();
t、 填充整数();
}
}
您的php示例不返回int数组,而是返回int指针数组。这不是您在Java中可以做的事情,事实上,这不是您想在Java中做的事情。给出一个用例,可能有更好的方法来解决您的问题
如果您想返回一个其他人可以影响并包含为成员变量的对象,请执行此操作。数组列表、哈希映射等。。。有很多东西可以满足你的需要。如果您被授予其他人的类,并且您必须关注他们的代码,您可以通过执行以下操作绕过他们的私有声明:
public void setN(JustTest j, int n) {
//You would handle some exceptions here also
Field f = JustTest.class.getDeclaredField("n");
f.setInt(j, n);
}
不能在没有反射的情况下执行单个字段,但可以更改集合的内容。请注意,这并不是真正的预期行为,而是在使用集合时必须小心的事情
这将输出53244
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);
}
}
公共类测试
{
公共向量args=新向量();
公共空白填充符()
{
增加(5);
增加(3);
}
公共向量getArgs()
{
返回args;
}
公共静态void main(字符串参数[])
{
测试s=新测试();
s、 fillArgs();
向量temp=s.getArgs();
用于(整数i:temp)
系统输出打印LN(i);
温度设置元件(2,0);
温度设定元件(4,1);
用于(整数i:temp)
系统输出打印LN(i);
对于(整数i:s.getArgs())
系统输出打印LN(i);
}
}
Q:怎么做?答:你没有实现这一点!你可以通过反射做类似的事情,但我不明白为什么有人会需要这样的东西。仅供参考:“链接”实际上被称为引用。您正在通过引用传递变量,或引用该变量的位置。链接通常是为了在编译可执行文件时整合目标代码而保留的。Q:如何?答:您使用JNI(Java本机接口),这样您就可以使用带有引用的代码,并将结果返回给Java用户,因为您已经更新了问题@L7ColWinters它看起来像解决方案,但它已经不是java了(使用instanceOf检查它是哪个子级是的,反射..但我不想使用它这意味着我需要使用反射api或甚至不使用java。谢谢。这需要重写TestClass。它不能解决在现有不可修改类的多个成员上执行相同操作而无需代码重复的问题。我需要使用fIELD。而不是数组或集合。更新的唯一方法是将原语字段复制到新数组中。理想情况下,您只需在JustTest对象上公开setter