3

I have a question about "CONST" in java.

I want to know how to make like "const struct VAL &getVal()" in C-Language.

Here is sample code.

public class test {
   /* VAL is just structure-like class */
   class VAL {
    public int i;
   };
   private VAL  val;

   /* test class functions */
   test() {
    val = new VAL();
    val.i = 1;
   }

   VAL getVal() {
    return val;
   }

   /* main function */
   public static void main(String[] args) {
    test t = new test();
    VAL  t_val;

    t_val = t.getVal();

    t_val.i = 2; /* it should be error if t_val variable is a const */
    System.out.printf("%d %d\n", t.getVal().i, t_val.i);
   }
}

below is C sample code.

struct VAL
{
    int i;
};

const struct VAL &getVal() /* THIS IS WHAT I WANT */
{
    static VAL xxx;
    return xxx;
}

int main()
{
    const VAL &val = getVal();
    val.i = 0; /* error */

    VAL val2 = getVal();
    val2.i = 0; /* it's not an error, but it's ok because it cannot be changed xxx variable in getVal() either. */

    return 0;
}
amit
  • 175,853
  • 27
  • 231
  • 333
killinggun
  • 101
  • 2
  • 7
  • 1
    Why do you exactly need that structure to be inmutable? If the problem is that it pertains to a data structure that should not be changed externally, then you could maybe return a copy of the structure instead of the structure itself, and therefore changes in the returned structure won't affect the main data structure. – Baltasarq Jun 30 '11 at 11:01
  • possible duplicate of [Why is there no Constant keyword in Java?](http://stackoverflow.com/questions/2735736/why-is-there-no-constant-keyword-in-java) – Mechanical snail Aug 06 '12 at 13:19

7 Answers7

1

final keyword have similar semantics. You cannot change object's reference, however you can change the object itself if it is mutable. I'd suggest to google it and read more about it.

Thresh
  • 943
  • 14
  • 23
  • I don't wanna change the return variable. I want to BLOCK changing the return value. – killinggun Jun 30 '11 at 10:43
  • @kellinggun Do you mean object reference or primitive value. In case of object reference, the only way I see is to make this class immutable. Make all fields and setter methods private. That way you will be sure that noone can change it. If you mean primitive values, they are always passed by value. – Thresh Jun 30 '11 at 10:46
  • 'final keyword have similar semantics': No it doesn't. There is no such thing as a C++ reference in Java, and 'final' has different semantics from 'const &'. Wrong answer. – user207421 Jun 30 '11 at 10:57
  • @EJP It is similar but not exactly same. If you use `final` on a primitive it has the same effect as const. Am I wrong again? – Thresh Jun 30 '11 at 11:03
  • it is really different. 'const' affects calling sequence signatures; 'final' doesn't. 'const' can be used with '&' which doesn't exist in Java. The similarities are fewer than the differences. – user207421 Jun 30 '11 at 11:06
1

you can't do the exact same thing like in C. Even though you use final keyword, it only prevent the modification of variable reference. t_val.i = 2 will be error if i is declared as final attribute.

yogiebiz
  • 386
  • 1
  • 9
1

Make the member variables of VAL private, and provide public getters. If you still want someone else to be able to change the members after initialization, you can use an interface with only getters, and an implementing class with public setters as well. Then, return the interface of the class, so the caller cannot change its members.

interface ValGetters {
   public int getI();
}

class Val implements ValGetters {
   private int i;
   public int getI() { return i; }
   public void setI(int ii) { i = ii; }
}

Internally, hold a Val. When you want to let someone else use it, return as ValGetters.

Eran
  • 21,632
  • 6
  • 56
  • 89
  • I have an another question about your answer. – killinggun Jun 30 '11 at 11:00
  • Can I try type casting from ValGetter object to Val object? Like this "Val val = (Val) valgetter;" – killinggun Jun 30 '11 at 11:01
  • @killinggun Yes, you can do that. But if you're worried about someone trying to hack your code, you can make `class Val` private, and `interface ValGetters` public. This way, assuming Val is nested, you can use Val only from within the nesting class (you can also make it a regular class, but not a public one, so it's only accessible from within your package). But anyway, OOP is about contracts. If someone casts it back to Val and then you change the implementing class of ValGetters to Val2, his code will crash at runtime. – Eran Jun 30 '11 at 11:20
1

const struct VAL &getVal() /* THIS IS WHAT I WANT */

There is no such construct in Java, all answers to the contrary notwithstanding, and especially those that suggest the 'final' keyword.

user207421
  • 305,947
  • 44
  • 307
  • 483
0

Short answer is you cant, at least not in a general sense. You CAN if you use all primitives(or classes you create that are all primitives), and a very small number of classes(String comes to mind), but you CANNOT do it in a general sense as you have no control over what people do with your objects after calling the getter method. If you want to do this, you have 2 options:

  1. Make all your FIELDS(not your class, your FIELDS, in this case i) final, that way people cannot change them.

  2. Make all your fields private and dont create any public setters(this is the preferred method)

However, going back to my original point:

Suppose val was defined like this:

public class VAL {
        private List<Integer> i=new ArrayList<Integer>();
        public VAL() {
            i.add(3);
         }
        public List<Integer> getI() {return i;}
       };

Now nobody can come along and change the object your list is pointing to, but they can very well change what i is pointing to, but code like this is perfectly valid(and it is valid even if i is marked final):

VAL bob=new VAL();
System.out.println(bob.getI().size());
bob.getI().clear();
System.out.println(bob.getI().size());

The above code will print out 1 0

Meaning that although i didnt change, your list contents did........

user439407
  • 1,666
  • 2
  • 19
  • 40
0

Better approach is to use enum. They are very powerful. You can use it in switch statement, and can have inner properties as you need with struct. You can look for documentation at http://download.oracle.com/javase/tutorial/java/javaOO/enum.html.

Zemzela
  • 3,060
  • 6
  • 23
  • 32
-3

use final keyword. It is analogue for const

David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
Penkov Vladimir
  • 921
  • 5
  • 10