1

Let's say I've made an instance of a class A which includes a field int value.

int D;
A test = new A();
test.value = 3;

I want to make a variable D which will be linked to this test value of the class instance. Whenever this value changes my variable D will change to. I can do that if I know the link. I could simply do the following when a change occurs :

D = test.value;

However, let's say that I want D to be linked to different values(from other instances, let's say test2, test3) as the program runs. In that case I could use switch statements and have a different command depending on the link.

switch (help_var):
    case 1:
        D = test.value;
        break;
    case 2:
        D = test2.value;
        break;
    case 3:
        D = test3.value;
        break;

A changing pointer would be very useful. As the program runs, my pointer will change. In C, I would do the following in every case:

D = *pointer;

Is there a way to put the (test.value) reference in a variable and use something like this in Java?

Turing85
  • 18,217
  • 7
  • 33
  • 58
John Katsantas
  • 571
  • 6
  • 20
  • I'm not sure what exactly you are trying or asking. – Ravi Jan 13 '18 at 14:30
  • The value of `D` will not be automatically updated when the value of, e.g., `test.value` is changed. For this, you would neet do deplay an `int *`, pointing to `test.value`'s address. This behaviour is not desirable in Java, since it breaks encapsulation: you could change `D`'s (and, in return, `test.value`'s value) from outside the object and thus break encapsulation. – Turing85 Jan 13 '18 at 14:31
  • @Ravi Sorry for not being clear as my English is really bad when it comes to coding. I want to somehow store the address of the changing value in a variable and then,using that variable , change D ( D=*pointer). – John Katsantas Jan 13 '18 at 14:35
  • @JohnKatsantas So, I would put it this way, you need to change value of this whenever `test.value` changes. is it ?? – Ravi Jan 13 '18 at 14:36
  • @JohnKatsantas `D = *pointer` stores the pointed-to value in `D`, not the address. `int DPointer = pointer` (provided that `pointer` is of type `int *`) would store the address. – Turing85 Jan 13 '18 at 14:36
  • @JohnKatsantas could you please clarify which exact behaviour you are looking for? As I pointed out, in your C example, value `D` does not automatically update. I think that you are looking for something like the [Observer Pattern](https://en.wikipedia.org/wiki/Observer_pattern). – Turing85 Jan 13 '18 at 14:52
  • @Turing85 The pointer is a changing pointer . Sorry again for not being that clear in the question . I will be the one detecting the change and whenever it happens this line of code ,changing D, will run . The pointer will point at different values as the program runs. – John Katsantas Jan 13 '18 at 15:08

5 Answers5

3

It turns out, that since version 1.8 java already has this functionality built-in with the IntegerProperty class, but since its API somehow outscopes this question, let me give a minimalist example, too:

public class IntContainer {
    private int i;

    public int getValue();
    public void setValue(int value);

}

Such a container class will do about the same as a C pointer, though comparing them does not make sense in the first place.
However, when you replace int value with IntContainer pointer (or IntegerProperty) and change the IntContainer's value, the modification will be visible for every instance holding a reference to the same IntContainer.

Izruo
  • 2,246
  • 1
  • 11
  • 23
  • Java (since version 8) already has "build in container*: Properties... – Timothy Truckle Jan 13 '18 at 14:49
  • @TimothyTruckle Are you referring to [`Properties`](https://docs.oracle.com/javase/9/docs/api/java/util/Properties.html)? Because that seems to be more like a key-value-mapping. – Izruo Jan 13 '18 at 14:51
  • 2
    https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/IntegerProperty.html – Timothy Truckle Jan 13 '18 at 14:53
  • @TimothyTruckle Thanks, I included it. – Izruo Jan 13 '18 at 15:03
  • Still the same problem as with haaawk's answer: it violates *encapsulation* and should be avoided. – Timothy Truckle Jan 13 '18 at 15:09
  • 1
    @TimothyTruckle Encapsulation is a mechanism, not a paradigm. A class may decide to expose some of the properties it's working on, let it be by setters or by wrapping objects around them; ether way it has to handle such properties with additional care. – Izruo Jan 13 '18 at 15:19
  • *"A class may decide to expose some of the properties"* There are basically two kinds of classes. One is *Data Transfer Objects* (DTO) or *Value Objects* without any business logic (beyond very simple validations). They actually do provide access to their internal structure (via getters and setters). The rest should not expose its internals since this supports *feature envy* and in consequence *code duplication* often accompanied by *odd ball solutions*. This all makes *maintenance* hard. – Timothy Truckle Jan 13 '18 at 15:52
1

You approach violates the encapsulation or information hiding principle by accessing an internal property of class A.

To come around this you should move the calculation working with that value to either a separate method in class A (if it somehow depends on A or its subclasses ) or another class that you can pass to a method of class A so that A can pass its value in:

interface MyCalculation{
  int calculateWith(inf value);
}

class A {
  inf test = 42;

  int doThis(MyCalculation calculation){
    return calculation.calculateWith(test);
  }
}

// somewhere else:

A a = new A();
int D = a.doThis(value->42*value);
Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
0

As you already noticed there aren't any pointers in Java.

So you need to create some wrappers to achieve the desired behavior, especially for primitive types like int.

One option is as @Izruo already answered to embed the values into an wrapper, with a custom class or with something like IntegerProperty.

Another option is to create a create a callback which returns the value of the desired variable. (Which is basically the idea behind @Timothy Truckle answer.)

For example with Supplier<T>:

public class Callback<T> {
    private Supplier<T> supplier;

    public void link(Supplier<T> to) {
        supplier = to;
    }

    public T get() {
        if(supplier == null)
            return null;
        return supplier.get();
    }
}

To link the values you can then use:

Callback<Integer> d = new Callback<>();
d.link(() -> test.value);
System.out.println(d.get());
Edwardth
  • 697
  • 1
  • 4
  • 14
0

Simple answer : you cannot do that in Java.

If you want to emulate it, you will have to emulate create "mutable" Integer object.

public class MutableInteger {
  private int value=0;
  public void setValue(int i){
      value=i;
  }
  public int getValue(){
     return value;
  }
}

You then can write :

MutableInteger D;
A test = new A();
test.value = new MutableInteger() ;
D=test.value;

That way, modify test.value will impact D and vice-versa

BluEOS
  • 576
  • 6
  • 13
-1

In Java, you can have only references to objects. int is a primitive type and not an object. This means you can't have reference to a field of int type.

Sometimes people do a workaround of using an array of size 1 (int[1]) which is an object and can be referred to by reference.

haaawk
  • 330
  • 1
  • 8
  • 1
    "*which is a primitive type not an object. This means it's always passed by value.*" - While this statement is true, it should be noted that [Java is pass-by-value always](https://stackoverflow.com/a/40523/4216641). – Turing85 Jan 13 '18 at 14:27
  • *"The problem is that A.test is an int"* - No. The problem is that the OPs approach violates the *encapsulation* or *information hiding* principle by accessing an *internal property* of class `A`. – Timothy Truckle Jan 13 '18 at 14:27
  • @Turing85 Yes. but objects are never referred to by their value. Always by a reference to this object. The reference itself is passed by value as you said. – haaawk Jan 13 '18 at 14:28
  • @TimothyTruckle The question is not about the style or OOP. The approach is not in question here. If a field of A is public and accessible then it's not an internal property of a class A. If it was private then it wouldn't be accessible and the whole approach wouldn't be possible. – haaawk Jan 13 '18 at 14:31
  • @TimothyTruckle Since the internal state is a primitive, a copy is returned, thus encapsulation is not broken. Even in the C example, OP only reads the value, and the value of `D` is not changed, when `test.value` is changed. – Turing85 Jan 13 '18 at 14:31
  • @Turing85 Its not about *safety*, its about *maintainability* and *extendability*. – Timothy Truckle Jan 13 '18 at 14:33
  • @haaawk wel, wenn coding in Java you *should* do OOP. Otherwise just don't use Java... – Timothy Truckle Jan 13 '18 at 14:35
  • @TimothyTruckle maintainability and extendability has nothing to do with this question. The question was "Is there a way to put the (test.value) reference in a variable". And the answer is yes for objects, no for primitive types. – haaawk Jan 13 '18 at 14:35
  • @haaawk *"maintainability and extendability has nothing to do with this question"* I argue that. Most code being hard to maintain is due such programmers like the OP and the commenters avoiding OOP at all costs... – Timothy Truckle Jan 13 '18 at 14:40
  • @TimothyTruckle I never talked about safety, maintainability or extensability. I just talked about encapsulation... – Turing85 Jan 13 '18 at 14:41
  • @Turing85 Don't you see that proper encapsulation is more that "the value cannot be changed from outside"? – Timothy Truckle Jan 13 '18 at 14:44
  • @TimothyTruckle Don't you see that the question is about what you can/can't do in Java? Not about what you should/shouldn't do. Knowing what is possible in the language and what's not is one thing and knowing good software engineering is the other. – haaawk Jan 13 '18 at 14:44
  • @haaawk And my initial comment was why your suggestion to use an object type instead of a primitive does not solve the problem. – Timothy Truckle Jan 13 '18 at 14:46