In PL/SQL (or many other languages), I can have IN OUT or OUT parameters, which are returned from a procedure. How can I achieve a similar thing in Java?
I know this trick:
public void method(String in, String[] inOut, String[] inOut2) {
inOut[0] = in;
}
Where the in parameter represents an IN parameter and the inOut parameter can hold a return value. The convention would be that String[] inOut is an array of inOut.length == 1.
That's kind of clumsy.
EDIT Feedback to answers: Other tricks include:
holder/wrapper classes, but I don't want to introduce any new types, callbacks, etc.
return values: I'd like a general solution. I.e. one with several IN OUT parameters involved.
wrapper for IN OUT parameter as a return value: That's a viable option, but still not so nice, because that wrapper would have to be generated somehow
Does anyone know a better way to achieve this generally? The reason I need a general solution is because I want to generate convenience source code from PL/SQL in a database schema.
My question would be: Why doesn't method return something? Rather than setting an in/out argument?
But assuming you absolutely, positively must have an in/out argument, which is a whole different question, then the array trick is fine. Alternately, it's not less clumsy, but the other way is to pass in an object reference:
public class Foo {
private String value;
public Foo(String v) {
this.value = v;
}
public String getValue() {
return this.value;
}
public void setValue(String v) {
this.value = v;
}
}
// ....
public void method(String in, Foo inOut) {
inOut.setValue(in);
}
(Or, of course, just make value public.) See? I said it wasn't less clumsy.
But I'd ask again: Can't method return something? And if it needs to return multiple things, can't it return an object instance with properties for those things?
Off-topic: This is one of the areas where I really like the C# approach. One of the arguments against in/out arguments is that they're unclear at the point where you're calling the function. So C# makes you make it clear, by specifying the keyword both at the declaration of the function and when calling it. In the absense of that kind of syntactic help, I'd avoid "simulating" in/out arguments.
Java copies anything you pass as an argument. If you pass a primitive, inside method you have copy of that primitive, and no modifications will affect the actual variable outside method. If you pass object, you pass copy of reference, which actually references to the original object. This is the way how you can propagate modifications to the context of something that called the method - by modifying the state of the object that the reference is 'pointing' to. See more on this: Does Java Pass by Value or by Reference?
There's no direct way. Other technique include:
Passing a holder object (a bit like your 1-ary array)
Using, e.g., an AtomicInteger
Passing a more useful object from a business perspective that happens to be mutable
A callback to a custom interface for receiving the result
If you think about it, the array trick is not dissimilar to passing a T* in C/C++
Related
In Java, a method could be defined as following:
Object m(boolean b) {
if (b) {
return "123";
} else {
return new Integer(123);
}
}
In this case, the return value of m could be either String or Integer in runtime. So is there any way to get all possible run time return types of a method in static time?
For this particular method, yes. Just call it with true and false and check the return value with getClass(). For a general case, no.
Generally you wouldn't need to either. Thanks to Java's strong typing and generics, the type of the return value should never be a huge surprise.
Returning multiple different types as shown in your example should be avoided, and in cases where it's useful/necessary (such as factory pattern) it should be irrelevant to the caller.
If you know the implementation of the method, yes. You know all the types it could return because you can read the code and tell for yourself what they are.
But, programmatically? For any method, in general? No, you can't do that, not at run-time. This is why it's very important to write good, sensical method signatures with meaningful return-types. Returning Object is seldom the best idea. When you say that your method returns Object, the contract of that method is that literally anything is allowed to come out of it. There's nothing wrong with that, but that's the most specific thing you can say about a method if all you know is its signature.
I'm a complete Java noob. I know that Java treats all parameters as pass by value and there are several other threads where people explain this.
For example, in C++ I can do:
void makeAThree(int &n)
{
n = 3;
}
int main()
{
int myInt = 4;
makeAThree(myInt);
cout << myInt;
}
Which will output 3. I know that in Java, all parameters are passed by value and thus you can not manipulate the parameter passed in. Is there a standard way to simulate pass by reference in Java? Is there no way to call a function that manipulates a variable passed in? It's tough for me to wrap my head around the idea of there being no way to do this.
The primary way you can simulate passing a reference is to pass a container that holds the value.
static void makeAThree(Reference<Integer> ref)
{
ref.set(3);
}
public static void main(String[] args)
{
Reference<Integer> myInt = new Reference<>(4);
makeAThree(myInt);
System.out.println(myInt.get());
}
Since in Java, it is references to objects that are passed by value (the object itself is never passed at all), setting ref to 3 in makeAThree changes the same object referred to by myInt in main().
Disclaimer: Reference isn't a class you can just use with out-of-the-box Java. I'm using it here as a placeholder for any other object type. Here's a very simple implementation:
public class Reference<T> {
private T referent;
public Reference(T initialValue) {
referent = initialValue;
}
public void set(T newVal) {
referent = newVal;
}
public T get() {
return referent;
}
}
Edit
That's not to say it's great practice to modify the arguments to your method. Often this would be considered a side-effect. Usually it is best practice to limit the outputs of your method to the return value and this (if the method is an instance method). Modifying an argument is a very "C" way of designing a method and doesn't map well to object-oriented programming.
You can use an array of size 1
Java pass everything by value, if it's an object then what would be passed is the reference value of the object. It's like,
void someMethod()
{
int value = 4;
changeInt(value);
System.out.printlin(value);
}
public void changeInt(int x)
{
x = x + 1;
}
above code will print 4, because it's passed by value
class SomeClass
{
int x;
}
void someMethod()
{
SomeClass value = new SomeClass();
value.x = 4;
changeCls(value);
System.out.printlin(value.x);
}
public void changeCls(SomeClass cls)
{
cls = new SomeClass();
cls.x = 5;
}
Above code will still print 4, because the object is passed by value and the reference to the object is passed here, even it's changed inside the method it won't reflect to the method 'someMethod'.
class SomeClass
{
int x;
}
void someMethod()
{
SomeClass value = new SomeClass();
value.x = 4;
changeCls(value);
System.out.printlin(value.x);
}
public void changeCls(SomeClass cls)
{
cls.x = cls.x + 1;
}
here also it passes the object by value, and this value will be the reference to the object. So when you change some field of this object it will reflect to the all the places where the object is referred. Hence it would print 5. So this can be the way you can use to do what you want. Encapsulate the value in an object and pass it to the method where you want to change it.
Java is pass-by-value that mean pass-by-copy. We cannot do arithmetic on a reference variable as in C++. In-short Java is not C/C++.
So as a workaround you can do this:
public static void main (String [] args) {
int myInt = 4;
myInt = makeAThree(myInt);
}
static int makeAThree(int n)
{
return n = 3;
}
P.S. Just made the method static so as to use it without class object. No other intention. ;)
I ran some of the various scenarios above.
Yes, if you wanted to change a value outside of the function without returning the same primitive, you'd have to pass it a single unit array of that primitive. HOWEVER, in Java, Array's are all internal objects. You please note that if you pass 'value' by name to the println() there is no compile error and it prints hashes because of the toString() native to the internal array class. You will note that those names change as they print (put it in a long loop and watch). Sadly, Java hasn't gotten the idea that we WOULD like a protected yet physically static address space available to us for certain reasons. It would hurt Java's security mechanisms though. The fact that we can't depend on known addresses means that it's harder to hack at that. Java performance is fantastic because we have fast processors. If you need faster or smaller, that's for other languages. I remember this from way back when in 1999 reading an article in Dobbs just about this argument. Since it's a web aware language meant to function online, this was a big design concession to security. Your PC in 1999 had 64mb to 256mb of RAM and ran around 800mhz
Today, your mobile device has 2 to 8 times that ram and is 200-700mhz faster and does WAY more ops per tick, and Java is the preferred language for Android, the dominant OS by unit sales (iOS still rocks, i gotta learn Objective C someday i guess, hate the syntax i've seen though).
If you passed int[] instead of int to this code you get 5 back from someMethod() calling it.
public void changeInt(int x)
{
x = x + 1;
}
public void changeInt(int[] x)
{
x[0] += 1;
}
This is a confusing selection from above. The code WOULD work if the author hadn't hidden the passed variable by declaring a local variable of the same name. OFCOURSE this isn't going to work, ignore the following example cited from above for clarity.
public void changeCls(SomeClass cls)
{
cls = new SomeClass();
cls.x = 5;
}
Above code will still print 4, because the passed object is HIDDEN FROM SCOPE by the local declaration. Also, this is inside a method, so I think even calling this and super wouldn't clarify it properly.
If it weren't hidden locally in the method, then it would have changed the value of the object passed externally.
To accomplish the changing of a primitive variable in a method there are 2 basic options :
1) If you want to change values on a primitive in a different method you can wrap the primitive in a "java bean" object, which will be essentially like a pointer.
Or
2) You can use an AtomicInteger/AtomicLong class which are used to concurrency, when many threads might need to modify a variable....so the variables has to have state that is consistent. Theses classes wrap primitives for you.
Warning : you are usually better off returning the new value, rather than setting/editting it internally in a method, from a maintainability standpoint ..
One quick way to achieving simulate passing by reference is to move the arguments to member variables of the enclosing class.
Although there are multiple ways to do it such as using a class or array wrapper or moving them to the function return type, the code may not turn out clean. If you are like me, the reason to ask such a question is that a piece of Java code has already been coded in a C++ way (which does not work) and a quick fix is needed. For example, in a recursion program such as depth-first-search, we may need to keep multiple variables in the C++ recursion function's argument list such as search path, flags whether the search should end. If you are in such a situation, the quickest fix is to make these argument variables into class member variables. Take care of the variable life cycle though and reset their values when necessary.
Java uses pass by value for everything.
As far as I understand you are not really sure if you can modify a variable passed in.
When you pass an object to a method, and if you use that object within that method, you are actually modifying that object. However you are modifying that object on a copy of it which still points to the same object. So actually when you pass an object to a method, you can modify it.
Once again, everything in java is pass by value.period.
I have a function in which I have to send two states of an object:
void functionA(MyObject objStateOff, MyObject objStateOn){
}
And there would always be only two types states: on and off
But instead of having two parameters of the same type for this function, I was hoping to combine them. SO I was thinking of having a HashMap<Boolean, MyObject>.
But since this map would at most contain only two entries, it seems to be a waste of resources, as I am developing for Android.
So, is there a better way of passing these two objects, without having two either use a HashMap or having two parameters in the function signature?
Update: I want to see if any other method would basically improve the following:
Readability, performance(even though i think that won't change) and maintainability
Thanks.
I would create a custom class with two MyObject fields, and accessors for each. This has a couple big advantages based on your goals:
Readability: The accessor methods describe what each object does. states.get(true), what does that mean? states.getFooOnState(), that's pretty clearly getting me the state for when foo is on.
Maintainability: Adding new state is much easier, if you ever need to do that; you just add a new field to this class. Maybe you'll want a MyObject for when the foo's state is unknown/initializing, or maybe you want to add event handlers that get triggered when foo gets turned on or off. One disadvantage to your current approach is that these sorts of things will cascade through your signatures: functionA needs to add a new argument, which means functionB which calls functionA needs to now get that extra parameter (so it can pass it to functionA), which means functionC needs to get it, and so on.
One caveat to the readibility issue is that you'll be gaining readibility where you use these MyObjects, but not where you first set them up. There, you'll be creating a new MyObjectState (or whatever you name it), and the constructor will look just as generic as your functionA:
MyObjectState s = new MyObjectState(objStateOff, objStateOn);
You could address that by creating a builder for MyObjectState, but that'd probably be overkill.
Performance wise, you're not going to get better than what you already have. But a custom class is going to add fairly minimal overhead (in terms of extra memory, GC activity, etc) in the grand scheme of things.
There's always the Pair class (http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/Pair.html). Or you could pass a MyObject[] with two elements.
I think this question doesn't have the only correct answer. Personally I would leave the function with two parameters, because that's not too much really and names of this parameters can help me to avoid confusion like "which element of map/array is for on state?".
You can always use composition.
Create a class that contains two objects of MyObject type.
It may look overkill at first, but it's safer than array.
Hope this helps.
You could use a simple ArrayList.
ArrayList<MyObject> a = new ArrayList<MyObject>();
a.add(objStateOff); a.add(objStateOn);
void functionA(ArrayList<MyObject>) {
...
}
functionA(a);
Or a simple argument logic:
void functionA(int x) {
MyObject state;
if (x == 0) {
MyObject state = objStateOff; // Supposing they were defined somewhere before.
} else if (x == 1) {
MyObject state = objStateOn;
}
if (state != null) {
// Use MyObject state.
}
}
In this way, you don't need to specify any convention, you just set the off or on right on the argument (You can use a string or a boolean instead of an int (I mean, you could use "ON" or "OFF", literally)).
if your requirement is to have two object states, then why you dont have a field in MyObject like boolean stateOfObject. Then in functionA, you can check the state and do the required logic. Why complicate by sending two objects when you have only two states? May be you have to mention the context where you are using it and why you need two objects to be passed to the functions when the object can be in only one state.
May be you could use enums:
public enum StateOfObject {
ON(10,2),
OFF(15,5);
private final int length;
private final int speed;
StateOfObject(int length, int speed) {
this.length = length;
this.speed = speed;
}
public MyObject getObject() {
MyObject myObj = new MyObject();
myObj.setLength(this.length);
myObj.setSpeed(this.speed);
return myObj;
}
}
Use it like this:
MyObject onObject = StateOfObject.ON.getObject();
System.out.print("Length: " + onObject.getLength() +
" Speed: " + onObject.getSpeed());
I am pretty new to Java, I have to convert C/C++ code to Java and I am running into obstacles. Because of the way variables are passed to the methods, their modification in the method is not straightforward, and I have no idea what is the most reasonable approach to take. Sorry for the pseudocode examples, I hope they will clearly explain what I am talking about without delving into unnecessary details.
I need something that would be equivalent to C
ModifyMyString(type1 &t1,type2 &t2);
(return type doesn't matter, it can be void) as I need the function to modify both t1 and t2.
I can easily modify one of the variables, say t1, by declaring in Java
type1 modifyMyString(type1 t1, type2 t2);
and assigning the returned value to
t1 = modifyMyString(t1,t2);
but it is only half of a success, as the new value of t2 is lost.
I can declare new class
class JustToPassTwoVariables {
type1 t1;
type2 t2;
JustToPassTwoVariables(type1 tt1, type2 tt2) { t1 = tt1; t2 = tt2; }
}
and do something like
JustToPassTwoVariables jtptv = modifyMyString(JustToPassTwoVariables(t1,t2));
but I feel like it is clumsy and makes the code unreadable.
In desperation I could also resign the idea of using a modifyMyString method, and repeat all the code locally in each place I would call modifyMyString - but it makes even less sense than using JustToPassTwoVariables class.
Is there a correct (or at least widely used, accepted as a standard, whatever) strategy to code such things in Java?
The recommended way in java is (in some people's opinion the clumsy way) to create a class containing the two fields and return an instance of that class.
I feel that it is much less clumsy if you stop and think about what the method is actually doing, and taking care to properly name both the method and the class returning the two values.
The simple answer is no. This sort of feature is not allowed in Java.
The correct way to do it is to pass in the object to be modified not the two variables. After all in virtually all cases those variables are already wrapped in an object, in cases where they aren't they often easily can be.
Either split the function into two functions and call it once for each variable, or wrap the variables into an object and pass that object into the function.
Don't forget Java allows Inner Classes which makes this sort of thing less painful.
You can't return two values from a method in java. The way is to return an object and set all the values in it. i.e. In your case, you need to create a value container class i.e. say Result class that will have two fields storing the type1 and type2 value in it. The return type of the method would be of value container object type i.e. say Result instance with two fields in it - type1 and type2
Example :
Result result = modifyMyString(t1,t2);
result.getT1(); //gets t1 value
result.getT2(); // gets t2 value
Please learn about setters and getters in Java to work on the class or object level fields
In Java if you want to do this you would generally make type1 and type2 into object whose values can be modified. The method can then modify the values of the parameters to get the desired effect. For example :
void myMethod(type1 arg0, type2 arg1) {
arg0.setValue(newValue0);
arg1.setValue(newValue1);
}
If type1 and/or type2 do not have any way of changing their values (e.g. they are of type String) then you would either make a wrapper class for each of them e.g.
class Type1Wrapper {
private type1 type1;
type1 getType1() {
return type1;
}
void setType1(type1 newType1) {
type1 = newType1;
}
}
or you would make a wrapper for both of the types simultaneously like you have in your question (although the method return type will be void and the method will modify your wrapper's values)
There are several methods to modify a group of objects "of the same type/class". The simplest of them being, add them to a "list" pass that list to your modification function, do whatever modifications/additions/deletions etc.. The list reference will be automatically available outside with the "changes made in the called function" .
So, you can do
List<String> l = new ArrayList<String>();
l.add("Hello");
l.add("world");
ModifyMyString(l);
// here also l = "hello" , "world" , "added"
public void ModifyMyString(List l)
{
l.add("added"); // now l = "hello" , "world" , "added"
}
Java is an OO language so to get the best out of it you should look to an OO solution. It's hard to give you a definite solution with this abstract example but this is how I would approach this.
You mention that t1 and t2 both need to be updated by this modify procedure/method. Also that they need to be updated at the same time, if they were unrelated then you could just call modify on each string in turn. If these two strings are related like this then it's likely they belong to the same type.
So we need a class containing type 1 and type 2.
public class TypeContainer
{
private String type1;
private String type2;
.. getters and setters
}
Obviously you'll want a better class name.
You suggest something similar yourself but call it JustToPassTwoVariables. This is missing the point of OO. You could write a simple wrapper like this and pass it to some other method to modify the values but a more OO approach would be to add the modify method to this class itself.
...
public void modfiy(String val1, String val2)
{
type1 = val1;
type2 = val2;
}
...
I'm not sure what your modify is trying to do but in this case I would probably have these as two separate setter methods. This is quite an abstract example!
Basically I would avoid having the modify method in some other unrelated class. You should look to group common related attributes into classes and then write methods in those classes for any actions you need to take (such as modify).
Trying to convert a procedural C program into an OO Java program sounds like a PITA. It's a complete paradigm shift. Having said that I have seen automated conversions which while technically Java are still very procedural. Not very pretty and hard to maintain but was done for political reasons.
Java discourages this strategy beacause in-variable should be immutable, but if you have to migrate from C/C++/C# and you have a lot of "void function with parameters passed as in/out", you can create a Custom "Reference" class like this and you can incapsulate the original object.
public class CustomRef {
public Object internal;
public CustomRef(Object object) {
this.internal=object;
}
}
then when you call
CustomRef ref1= new CustomRef(myParams1);
CustomRef ref2= new CustomRef(myParams2);
myFunction(ref1, ref2);
myParams1 = ref1.internal;
myParams2 = ref2.internal;
the function is
void myFunction(CustomRef ref1, CustomRef ref2) {
Object param1 = ref1.internal
// a lot of code
ref1.internal = param1;
}
really discouraged way ... such as using ArrayList, arrays [] to "pass by reference".
NOTE: this way is a waste of resource; CustomRef instance should be reused through object pool (another discouraged way).
I would use a StringBuffer. You can initialize it with a String and convert it back to a String
How can I pass a primitive type by reference in java? For instance, how do I make an int passed to a method modifiable?
There isn't a way to pass a primitive directly by reference in Java.
A workaround is to instead pass a reference to an instance of a wrapper class, which then contains the primitive as a member field. Such a wrapper class could be extremely simple to write for yourself:
public class IntRef { public int value; }
But how about some pre-built wrapper classes, so we don't have to write our own? OK:
The Apache commons-lang Mutable* classes:
Advantages: Good performance for single threaded use. Completeness.
Disadvantages: Introduces a third-party library dependency. No built-in concurrency controls.
Representative classes: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.
The java.util.concurrent.atomic Atomic* classes:
Advantages: Part of the standard Java (1.5+) API. Built-in concurrency controls.
Disadvantages: Small performance hit when used in a single-threaded setting. Missing direct support for some datatypes, e.g. there is no AtomicShort.
Representative classes: AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
Note: As user ColinD shows in his answer, AtomicReference can be used to approximate some of the missing classes, e.g. AtomicShort.
Length 1 primitive array
OscarRyz's answer demonstrates using a length 1 array to "wrap" a primitive value.
Advantages: Quick to write. Performant. No 3rd party library necessary.
Disadvantages: A little dirty. No built-in concurrency controls. Results in code that does not (clearly) self-document: is the array in the method signature there so I can pass multiple values? Or is it here as scaffolding for pass-by-reference emulation?
Also see
The answers to StackOverflow question "Mutable boolean field in Java".
My Opinion
In Java, you should strive to use the above approaches sparingly or not at all. In C it is common to use a function's return value to relay a status code (SUCCESS/FAILURE), while a function's actual output is relayed via one or more out-parameters. In Java, it is best to use Exceptions instead of return codes. This frees up method return values to be used for carrying the actual method output -- a design pattern which most Java programmers find to be more natural than out-parameters.
Nothing in java is passed by reference. It's all passed by value.
Edit: Both primitives and object types are passed by value. You can never alter the passed value/reference and expect the originating value/reference to change. Example:
String a;
int b;
doSomething(a, b);
...
public void doSomething(String myA, int myB) {
// whatever I do to "myA" and "myB" here will never ever ever change
// the "a" and "b"
}
The only way to get around this hurdle, regardless of it being a primitive or reference, is to pass a container object, or use the return value.
With a holder:
private class MyStringHolder {
String a;
MyStringHolder(String a) {
this.a = a;
}
}
MyStringHolder holdA = new MyStringHolder("something");
public void doSomething(MyStringHolder holder) {
// alter holder.a here and it changes.
}
With return value
int b = 42;
b = doSomething(b);
public int doSomething(int b) {
return b + 1;
}
Pass an AtomicInteger, AtomicBoolean, etc. instead. There isn't one for every primitive type, but you can use, say, an AtomicReference<Short> if necessary too.
Do note: there should very rarely be a need to do something like this in Java. When you want to do it, I'd recommend rethinking what you're trying to do and seeing if you can't do it some other way (using a method that returns an int, say... what exactly the best thing to do is will vary from situation to situation).
That's not possible in Java, as an alternative you can wrap it in a single element array.
void demo() {
int [] a = { 0 };
increment ( a )
}
void increment( int [] v ) {
v[0]++;
}
But there are always better options.
You can't. But you can return an integer which is a modified value
int i = 0;
i = doSomething(i);
If you are passing in more than one you may wish to create a Data Transfer Object (a class specifically to contain a set of variables which can be passed to classes).
Pass an object that has that value as a field.
That's not possible in Java
One option is to use classes like java.lang.Integer, then you're not passing a primitive at all.
On the other hand, you can just use code like:
int a = 5;
a = func(a);
and have func return the modified value.