Hey;

I'm getting into Java. I'm coming from C++ base and I wonder how can we use "const" parameters in Java?

For example if I don't want the function to be able to change the value of a parameter, what do I do?

void modify(RefObject parameter)
{
parameter.set(new RefObject); //should cause compiler error
}

All java parameters are call-by-value. (Remember that all variables that are not primitives are references to Objects, so it's the reference that's passed by value)
So in your example on line 3 parameter is a reference variable that contains a copy of the reference that was used in calling the method. Line 3 changes the value of parameter, but it has no effect whatsoever whatever was passed to the method. It is therefore impossible for a method to change the value of anything passed as a parameter.
Despite that, given a (copy of) a reference to some Object, a method can still modify the Object whose reference was passed, if that Object has mutator methods or public variables.

James, I think if RefObject is an object (and not a primitive), then modify should modify the original. I think the following code is a fuller example of what the OP had in mind:

public static void main(String[] args) {
		
		ArrayList<String> l = new ArrayList<String>();
		modifyArrayList(l);
		System.out.print("ArrayList l contains: ");
		for (String s:l)
			System.out.print(s+",");
		System.out.println();
	}

	private static void modifyArrayList(ArrayList<String> list)
	{
		list.add("foo");
	}

Output will be "ArrayList l contains: foo,".
The OP was trying to protect the original object from modification.

Unfortunately, "final" won't work here, because it'll only ensure that the value of "parameter" won't change: it'll continue to point to the same object. The state of that object can still change.

I don't have a great solution off the top of my head. It'll depend more on the circumstance, and what you're trying to protect against.

The simplest solution would be to make a deep copy of the object in question and pass that as your parameter:
If perfectCopyOf(RefObject r) returns a RefObject with the same values as r, then this code :

RefObject p = perfectCopyOf(r);
dangerousMethod(p);

will protect r from modification, while giving dangerousMethod() access to its values.

Edited 5 Years Ago by jon.kiparsky: n/a

Tellalca - what is it you're actually trying to do here? I have a few ideas, but I don't know if any of them make sense for your purposes.

"I think if RefObject is an object (and not a primitive), then modify should modify the original."
Yes, absolutely. I think that's what I said in my final sentence? You can modify an object when passed a reference to that Object, but you can't change the parameter, ie the reference itself.
I think this is the other side of the coin to the old chestnut "How do you write a simple swap method in Java like you can in C++ ?"

public void swap(int a, int b) {
  int temp =a;
  a = b;
  b = temp;
  // doh!
}

Edited 5 Years Ago by JamesCherrill: n/a

Thanks for replies. I'm actually looking for a way to protect my data from the "dangerous methods".

In C++ if you don't want a function to change your original data's state, you can pass it by call by value or to omit the overhead of copying you can pass it as "const" pointer or reference. So if the function tries to change your original data( not the parameter ) the compilation fails.

This way you put a layer of security and obey the OOP principles. In Java is it possible to force a permission check like this during compilation?

I hope I'm clear with that.

Edited 5 Years Ago by Tellalca: n/a

OK. Sorry I was answering the wrong question.
Simple answer AFAIK is "no", but there's always a way round if you try hard enough (eg Jon's deep copy). Is there a specific situation you're asking about, or is this just a general seeking of knowledge?

One way to do it would be to define the class as an immutable object. If you define the fields as final, or make them private and offer no setters, then you're protected.

For example:

public class Foo
{
  private String name;
  public Foo (String name)
  {
    this.name = name;
  }

  public String getName()
  {  
    return name;
  } 
}

This class, once created, is final. If you pass it to a method, that method can do what it wants with the name (print it out, shuffle its characters, whatever), but it can't change it.
Is that what you had in mind?

Thank you all. Yes that was what I wondering. I see there is no flexible and easy way.

This question has already been answered. Start a new discussion instead.