Java中的指针逻辑

时间:2012-12-23 09:17:22

标签: java pointers

我需要找到一种方法,通过getter函数直接修改Java中类的私有成员。我知道我可以使用像这样的指针在C ++中做到这一点;

class FooBar
{
    private:
        Foo foo;

    public:
        Foo* getFoo()
        {
            return &foo;
        }
}

然后我可以通过公共函数foo直接操作私有变量getFoo(),因为getFoo()返回一个指针(例如。getFoo()->callFunction();

所以我想知道的是,有没有办法在Java中复制这个完全相同的效果?? ....任何方式都可以吗?

7 个答案:

答案 0 :(得分:5)

class FooBar {
    private Foo foo;

    public Foo getFoo() {
        return foo;
    }
}

Java中的所有对象变量都是对象的引用,因此您可以将它们视为“锁定”指针。 “锁定”,因为你不能用它做任何指针运算。

答案 1 :(得分:2)

因为,Java没有Pointer。但是,你可以这样做,使用 getter setter ,它会帮助你这样做

class myclass{
private myclass val;  // private field

//get the private field
public myclass getVal(){
return val;
}

//set/change the member field value
public void setVal(myclass val){
this.val=val;
}

}

答案 2 :(得分:2)

在java中,getter返回对对象的引用,因此您可以依赖返回对象的公共方法来对其进行mofify。如果你详细说明你想做什么,我可以进一步详细说明。例如,

如果getter返回一个列表,调用者可以使用add或remove方法修改列表。

答案 3 :(得分:1)

您必须提供一个getter和一个setter

class FooBar {

    private Foo foo;

    public Foo getFoo() {
        return foo;
    }

    public void setFoo(Foo foo) {
        this.foo = foo;
    }

}

答案 4 :(得分:1)

您可以通过简单的getter访问您所需要的内容,如已经显示的那样。 一些重要细节:

如果你想想像

那样
getFoo()->callFunction();

请确保:

  • Foo 类是可见的(默认修饰符,如果你在同一个包中, protected 如果调用者是子类或 public < / em>否则)
  • callFunction()是可见的(相同的规则)

如果你想想像

那样
getFoo().value = newValue;

确保值是可修改的,这意味着类Foo不会将值定义为final:

class Foo {
    // in this case value is immutable
    final Bar value;
}

在最后一种情况下,编译器会告诉你,“无法分配最终字段Foo.value”。

答案 5 :(得分:0)

Java 按值传递,或者更具体地说,按值传递参考。这意味着传递所有引用类型:

List<String> a = myObj.getList();
a.add("My String"); // this modifies the source list

List<String> b = new ArrayList<String>();
a = b; // this doesn't change the source list's reference

当用Java编程时,大多数人尝试实现最高级别的封装,将可变类型转换为不可变类型(例如,使用复制构造函数)。这是在OOP空间中编程的好方法。

如果你没有setter,你可能想要使用Java的内置反射:

public class Test {
    private String NAME = "OLD NAME";

    public String getName() {
        return this.NAME;
    }

    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Test t = new Test();
        System.out.println(t.getName()); // OLD NAME

        Field f = t.getClass().getDeclaredField("NAME");
        f.setAccessible(true); // allows access to private field 
        f.set(t, "NEW NAME");

        System.out.println(t.getName()); // NEW NAME
    }
}

但要注意,反思是一个高级主题,在大多数情况下是编程错误的症状。

答案 6 :(得分:0)

即使在C ++中,这也是一个坏主意,因为如果对象被解除分配,您的指针现在将指向无效的内存位置。这是你在Java中没有指针的原因之一;为了保护从流氓指针访问的内存。因此,在Java中,所有对私有字段的访问必须通过封闭对象本身进行,通常使用get / set组合。

但是,我认为使用set()不是你想要的解决方案;可能是因为您拥有来自不同类的对象集合,这些对象不共享除Object之外的公共层次结构。如果是这种情况,那么潜在的解决方案是创建和使用通用接口。这样,您可以使用此通用接口存储这些不同对象的引用,并以相同的常用方式对其进行操作;例如:

static void test() {

    List<IntegerGetSet> list = new ArrayList<IntegerGetSet>();
    list.add (new A1(1));
    list.add (new B1(2));

    for (IntegerGetSet igs: list) {
        igs.set (igs.get() * 10);               
        System.out.println(igs.get()); 
    }
}

interface IntegerGetSet {   
    public int get();
    public void set (int i);
}

static class A1 implements IntegerGetSet {

    private int i;

    public A1 (int i) { this.i = i; }

    @Override
    public int get() {
        return i;
    }

    @Override
    public void set(int i) {
        this.i = i;
    }       
}

static class B1 implements IntegerGetSet {
    private int i;

    public B1 (int i) { this.i = i; }

    @Override
    public int get() {
        return i;
    }

    @Override
    public void set(int i) {
        this.i = i;
    }       
}

如果你不能修改这些课程,那么你将会有更复杂的东西做饭;例如,使用另一篇文章中建议的反射。