With a third party API I observed the following.
Instead of using,
public static string getString(){
return "Hello World";
}
it uses something like
public static void getString(String output){
}
and I am getting the "output" string assigned.
I am curious about the reason of implementing such functionality. What are the advantages of using such output parameters?
Something isn't right in your example.
class Foo {
public static void main(String[] args) {
String x = "foo";
getString(x);
System.out.println(x);
}
public static void getString(String output){
output = "Hello World"
}
}
In the above program, the string "foo" will be output, not "Hello World".
Some types are mutable, in which case you can modify an object passed into a function. For immutable types (such as String), you would have to build some sort of wrapper class that you can pass around instead:
class Holder<T> {
public Holder(T value) {
this.value = value;
}
public T value;
}
Then you can instead pass around the holder:
public static void main(String[] args) {
String x = "foo";
Holder<String> h = new Holder(x);
getString(h);
System.out.println(h.value);
}
public static void getString(Holder<String> output){
output.value = "Hello World"
}
That example is wrong, Java does not have output parameters.
One thing you could do to emulate this behaviour is:
public void doSomething(String[] output) {
output[0] = "Hello World!";
}
But IMHO this sucks on multiple levels. :)
If you want a method to return something, make it return it. If you need to return multiple objects, create a container class to put these objects into and return that.
I disagree with Jasper: "In my opinion, this is a really ugly and bad way to return more than one result".
In .NET there is a interesting construct that utilize the output parameters:
bool IDictionary.TryGet(key, out value);
I find it very usefull and elegant. And it is the most convenient way to aks if an item is in collection and return it at the same time. With it you may write:
object obj;
if (myList.TryGet(theKey, out obj))
{
... work with the obj;
}
I constantly scold my developers if I see old-style code like:
if (myList.Contains(theKey))
{
obj = myList.Get(theKey);
}
You see, it cuts the performance in half. In Java there is no way to differentiate null value of an existing item from non-existance of an item in a Map in one call. Sometimes this is necessary.
This functionality has one big disadvantage - it doesn't work. Function parameters are local to function and assigning to them doesn't have any impact outside the function.
On the other hand
void getString(StringBuilder builder) {
builder.delete(0, builder.length());
builder.append("hello world");
}
will work, but I see no advantages of doing this (except when you need to return more than one value).
Sometimes this mechanism can avoid creation of a new object.
Example:
If an appropriate object exists anyhow, it is faster to pass it to the method and get some field changed.
This is more efficient than creating a new object inside the called method, and returning and assigning its reference (producing garbage that needs to be collected sometime).
String are immutable, you cannot use Java's pseudo output parameters with immutable objects.
Also, the scope of output is limited to the getString method. If you change the output variable, the caller won't see a thing.
What you can do, however, is change the state of the parameter. Consider the following example:
void handle(Request r) {
doStuff(r.getContent());
r.changeState("foobar");
r.setHandled();
}
If you have a manager calling multiple handles with a single Request, you can change the state of the Request to allow further processing (by other handlers) on a modified content. The manager could also decide to stop processing.
Advantages:
You don't need to return a special object containing the new content and whether the processing should stop. That object would only be used once and creating the object waste memory and processing power.
You don't have to create another Request object and let the garbage collector get rid of the now obsolete old reference.
In some cases, you can't create a new object. For example, because that object was created using a factory, and you don't have access to it, or because the object had listeners and you don't know how to tell the objects that were listening to the old Request that they should instead listen to the new Request.
Actually, it is impossible to have out parameters in java but you can make a work around making the method take on a de-reference for the immutable String and primitives by either writing a generic class where the immutable is the generic with the value and setter and getter or by using an array where element 0 (1 in length) is the value provided it is instantiate first because there are situations where you need to return more than one value where having to write a class just to return them where the class is only used there is just a waste of text and not really re-usable.
Now being a C/C++ and also .Net (mono or MS), it urges me that java does not support at least a de-reference for primitives; so, I resort to the array instead.
Here is an example. Let's say you need to create a function (method) to check whether the index is valid in the array but you also want to return the remainding length after the index is validated. Let's call it in c as 'bool validate_index(int index, int arr_len, int&rem)'. A way to do this in java would be 'Boolean validate_index(int index, int arr_len, int[] rem1)'. rem1 just means the array hold 1 element.
public static Boolean validate_index(int index, int arr_len, int[] rem1)
{
if (index < 0 || arr_len <= 0) return false;
Boolean retVal = (index >= 0 && index < arr_len);
if (retVal && rem1 != null) rem1[0] = (arr_len - (index + 1));
return retVal;
}
Now if we use this we can get both the Boolean return and the remainder.
public static void main(String[] args)
{
int[] ints = int[]{1, 2, 3, 4, 5, 6};
int[] aRem = int[]{-1};
//because we can only scapegoat the de-ref we need to instantiate it first.
Boolean result = validate_index(3, ints.length, aRem);
System.out.println("Validation = " + result.toString());
System.out.println("Remainding elements equals " + aRem[0].toString());
}
puts: Validation = True
puts: Remainding elements equals 2
Array elements always either point to the object on the stack or the address of the object on the heap. So using it as a de-references is absolutely possible even for arrays by making it a double array instantiating it as myArrayPointer = new Class[1][] then passing it in because sometimes you don't know what the length of the array will until the call going through an algorithm like 'Boolean tryToGetArray(SomeObject o, T[][] ppArray)' which would be the same as in c/c++ as 'template bool tryToGetArray (SomeObject* p, T** ppArray)' or C# 'bool tryToGetArray(SomeObject o, ref T[] array)'.
It works and it works well as long as the [][] or [] is instantiate in memory first with at least one element.
in my opinion, this is useful when you have more than one result in a function.
Related
For a project I am working on, I have to retrieve some entries from a NoSQL database. The values may either be Strings or Doubles, however, at the time of calling the method that retrieves these values, I do not know what type of value the field contains.
For the sake of argument here is a minimal working example, which is of course oversimplified:
public class ReturnType {
public static void main(String[] args) {
String s = "This is a string.";
double d = 23.5;
getValue(s);
getValue(d);
}
private static Object getValue(Object obj) {
return obj;
}
}
I have thought about checking the class of the object that is returned by the function and casting the returned object to that class:
if (getValue(s).getClass() == String.class){
String result = s;
} else if (getValue(s).getClass() == double.class)
{
Double result = d;
}
However, I do not like this solution at all, as I have to hardcode every possible return type into an if or case statement.
I have also thought about creating an additional method that checks the class before calling the method retrieving the value and using different methods with different return types, depending on the result of that. But this seems just like the same approach, albeit implemented differently.
What would be a best practice solution to this problem?
I am new to java and I was writing some code to practice, but there is something that I am confused about. I have the following code:
public class test {
public static void main(String[]args) {
int n = 0;
ArrayList<String> fruits = new ArrayList();
setList(fruits);
n =setInt(9);
// get the values from fruits
for (String value: fruits) {
print(value);
}
}
public static void setList( ArrayList list) {
list.add("pear");
list.add("apple");
list.add("pear");
}
public static int setInt(int number) {
number = 3;
return number;
}
}
My question is why in order to set my Arraylist() there is no need to return the any value, but in order to set my int I need to return something.If run this code it prints all the values in my list, but I expected not to print anything because In my method setList I do not return any value. If I did not return any value with my setInt, the value of n would not change, and that makes sense to me.
Thank you.
There are different ways to that params get passed in functions. The usuall way that most beginners start with is pass by value. The other way is pass by reference. In passing by reference, the object itself is pass in, not a copy as is with pass by value. That means any changes will affect the param and remain, even after it is called. All objects in java are passed by reference, only primitives are passed by value. Thus, is why you don't have to return when using arraylist object.
Edit: Actually, I've made an error. What is actually occuring is that a copy of the reference itself is being passed by value. Take a look at this.
Everything in Java is Pass by Value.
Although I've programmed C, C++ and C# for many years I'm am only superficially familiar with Java. Helping my Comp Sci son with a Java college project he had a need to return references to two objects from a method in Java. I suggested returning one as the function value and the 2nd as a reference. He wasn't sure how to do this. I did a little research and realized it may not be possible. My question is in Java what is the common method used when a method needs to return more than one reference to an object. Here's the specific example in my sons case.
// This method returns references to the head and tail objects from the passed in
// linked list. The head object is returned as the function value and the tail is
// returned as a parameter.
public Static Node GetHeadTail(List list, Node tail)
I realize the above doesn't work in Java since the tail is a reference to node and in Java the reference itself is passed by value. What is the most common way of dealing with this in Java? My son's solution was to return an array of 2 Node objects for the function value. I said that was a poor solution because it doesn't document the meaning of each element of the array. Another solution would be to create an object that contained the head and tail references. However in the particular example it was the head pointer that was of most interest and if an object was returned it would create undesired coding overhead for the caller of the method if all they wanted was the head.
In this case, java programmers would commonly create a class with 2 members: head and tail. That would be the return type for the getHeadTail(List list) method.
Java does this interesting thing that's sort of a hybrid between pass-by-value and pass-by-reference. Basically, a parameter cannot be changed by the function, but the function can ask the parameter to change itself via calling some method within it. This answer does a pretty good job of explaining it.
In response to "What is the most common way of dealing with this in Java?" your solution of creating a class that contains a head and tail reference is probably the most common and best practice. If possible, it may even be best to just have separate getHead and getTail methods.
You can only pass by value in Java. Your best solution is the second one your son suggested, i.e. return an object that has the head and tail.
Java is always pass-by-value. The difficult thing can be to understand
that Java passes objects as references and those references are passed
by value. (Is Java "pass-by-reference" or "pass-by-value"?)
However, you are capable of doing something like this:
public static void main(String[] args)
{
Car c = new Car("Blue");
System.out.println(c.getName());
changer(c);
System.out.println(c.getName());
}
public static void changer(Car c)
{
c.setName("Red");
}
The Car class.
public class Car
{
private String name;
public Car(String n)
{
name = n;
}
public String getName()
{
return name;
}
public void setName(String n)
{
name = n;
}
}
The output will be:
Blue
Red
Knowing this, you will be able to change what tail points to and still be able to return the head.
One slightly less obvious solution: Use one of the built-in types, like Queue or LinkedList, which already has a head and tail.
LinkedList list = new LinkedList();
head = list.getFirst();
tail = list.getLast();
There's a bunch of types like this one depending on your need. Read the docs.
A somewhat hacky technique is to use a an array as a parameter. Then, the function can change the value of one or more element to "return" it. It's not pretty but gets the job done and avoids the need to create special wrapper objects for this purpose.
Just as a side note, Scala solves this issue by letting you return tuples.
If you are trying to implement a method that return multiple values as arguments, you can use something like this:
public class Future<T> {
private T instance;
public T get() {
return this.instance;
}
public void set(T value) {
this.instance = value;
}
}
And use it like this:
class MyCrazyClass {
private static void myCrazyMethod(Future<String> returnVal1, Future<Integer> returnVal2, Future<Float> returnVal3) {
returnVal1.set("We are cool!");
returnVal2.set(123);
returnVal3.set(321F);
}
public static void main(String[] args) {
Future<String> strRetVal = new Future<>();
Future<Integer> intRetVal = new Future<>();
Future<Float> floatRetVal = new Future<>();
myCrazyMethod(strRetVal, intRetVal, floatRetVal);
System.out.println(strRetVal.get());
System.out.println(intRetVal.get());
System.out.println(floatRetVal.get());
}
}
Output:
We are cool!
123
321.0
I know this issue has been addressed many times - but my Java/C++ knowledge is so weak I can barely understand the answers :-( ... what I'd really like is just a super simple example.
In C++ I could write the following:
void func()
{
int x = 3;
add_one(x);
// now x is 4.
}
void add_one(int &var)
{
var++;
}
What I'd like to see now is the simplest way to achieve the same effect with java.
You can't directly. The closest you can get is to put the value in an object, and pass the reference (by value, so the reference gets copied) into the method.
void func()
{
int x = 3;
int[] holder = [x];
add_one(holder);
// now holder[0] is 4. x is still 3.
}
// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
container[0]++;
}
Here I use an array, but the wrapper can be any object.
In java method arguments are pass-by-value, and can't be changed in the function. You must wrap the int - or any other primitive type - in an Object or an array. Passing an Object or an array as a method argument passes a reference which can be used to modify the object.
Java already has Object based wrappers for primitive types, e.g. Integer, but these are immutable by design. Some libraries provide mutable versions of these wrappers; you can also create your own:
public class MutableInt
{
private int val;
public MutableInt(int val)
{
this.val = val;
}
public void setValue(int newVal)
{
this.val = newVal;
}
public int getValue()
{
return this.val;
}
}
void func()
{
int x = 3;
MutableInt wrapper = new MutableInt(x);
add_one(wrapper);
}
void add_one(MutableInt arg)
{
arg.setValue(arg.getValue() + 1);
}
You cannot do this. Java is only pass by value. Primitives are obvious, but the thing that's passed for objects is a reference, not the object itself.
As you can see from the other answers, Java is purely pass by value. Objects are passed by what some call "value-reference". Since an object in java is simply a pointer reference, you can think of the "value" as the address where the object lives on the heap. So when you make a method call, you're copying the "value", aka address, to the method parameter:
Object x = new Object();
foo(x);
During object creation
Heap --> allocate Object (5000)
Variable Declaration
Stack --> allocate local variable (1000)
Variable Assignment
Stack address 1000 set to 5000 (to point to object instance)
So you can see that there are two separate memory allocations here. The "value" of the variable is considered to be it's address on the heap.
Method Call
Stack --> allocate method parameter 8000
Stack address 8000 set to same value as passed parameter 5000
This is why if you reassign an object instance in a method, it does not propagate back to the caller. You would have changed the heap location at stack location 8000. And the calling method's stack location 1000 still has the value 5000 (the original object instance).
Think of it like this in C:
void method(myobject * obj);
You can certainly change fields of "obj", and you can do this locally:
obj = new myobject();
But the caller will still see the original value it passed.
Java has no analog to the & reference operator.
And there are built in classes which can be used for the your purposes. AtomicInteger, AtomicLong, etc... are mutable, though you may suffer a performance hit due to synchronization involved.
I would recommend a generic ValueHolder class to account for all situations where you want to simulate pass by reference:
public class ValueHolder<T> {
private T value;
// getter/setter/constructor
}
Java allows copy by reference for objects and copy by vlaue for primitive types (int,float,etc..). This is so by default and is not subject to change. If you need to change the value of an int inside a function, then you can use the class Integer for example
public int getOneMore(int val) {
return val + 1;
}
I have a Java method something like this
public boolean ReadBool(String ValueName, Boolean Value)
{
boolean Retval = ...;
...
Value = true;
...
return bRetval;
}
that I call from native code (C++) like this:
jMethodID MethodId = pEnv->GetMethodID(ClassId, "ReadBool", "(Ljava/lang/String;Ljava/lang/Boolean;)Z");
// What goes instead of "??" ?
bool bOk = pEnv->CallBooleanMethod(myobject, MethodId, pEnv->NewStringUTF("Value1"), "??");
My intention is for the Java method to "return" a boolean value in Value. I understand that a built-in boolean will not work for this purpose. Is it possible to do this with a Boolean wrapper? How does one construct the object to pass in place of "??" ?
I have googled around, but some questions remain. For example, I suppose I could pass an object created by calling Boolean's <init> "method". But wouldn't the assignment in the Java ReadBool make Value refer to a newly created wrapper, throwing away that first object? In that case I would have called <init> for nothing. I think it should be possible to create (in the native code) something that Java sees as an object that is null and whose type is Boolean. Is that possible? Or am I on the wrong track altogether?
Booleans are immutable in Java, so you need your own wrapper class, which can be really simple though:
public class BooleanWrapper {
public boolean val;
// public is fine here imo, but you can obviously use [g|s]etters as well
}
Or if you don't want this, we can use a.. well not really pretty, but nice to know hack:
public void hack(boolean[] vals) {
vals[0] = true; // voila, now you change the value itself
}
Has some obvious drawbacks when calling (and looks strange), but if you're fine with keeping a specific parameter sequence, you can do:
public void hack(boolean.. vals) {
vals[0] = true; // voila, now you change the value itself
}
that way the caller doesn't have to use stuff like new boolean[] {};
You can obviously cheat and change the internal state of the Boolean object itself, but that will have unwanted consequences (booleans are cached ergo if you change the Boolean.TRUE instance to false internally this will give interesting results). So don't do that.