This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why there is no way to pass by reference in java
Can anybody tell me why exactly Java does not provide C# "out" type feature when dealing with method parameters to pass by reference ?
I mean why would not it allow us to pass primitive data types like boolean for example, pass by reference. I have tried also with wrapper class java.lang.Boolean but still to no avail. It still wont allow me to pass variable by reference.
Is there any specific reason why Java still has not provided us with this even in version 7 ?
Java only has pass by value. This was a decision made when the language was designed.
Why doesn't java support pass by reference like C++
There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple.
-- James Gosling, et al., The Java Programming Language, 4th Edition
If you want you can put your boolean as a member inside a mutable class (you can't use Boolean because it is immutable), and pass a reference to that class. Apache Commons even has a class called MutableBoolean that you can use.
Only the language design team could tell you why, but I believe the reason for not allowing "out" parameters might be something like: If you want a method that calculates two things, what you really want is either two methods, or one method that returns an object. This supposedly leads to better design and more maintainable code.
Note that you if you really want "out parameters" you can easily use arrays of one element. For example:
void div(int a, int b, int[] q, int[] r) {
if (q != null) q[0] = a/b;
if (r != null) r[0] = a%b;
}
// elsewhere:
int[] quotient = new int[1];
int[] remainder = new int[1];
div(4, 3, quotient, remainder);
This is just my opinion but I feel that the designers of Java believed they could simplify programming by eliminating features rather than making them more intuitive and easier to handle.
Short answer is that it's a design decision and there's nothing you can do with passing by reference that you couldn't do with passing object references by value.
As for your particular problem, there are two solutions:
A mutable wrapper class:
final class BooleanRef {
public boolean value;
}
And use it as:
// Function
void changeTheBoolean( BooleanRef b ){
b.value = true;
}
// Call:
BooleanRef b = new BooleanRef();
changeTheBoolean( b );
OR, (more hackish but more lightweight) wrap in an array:
// Function
void changeTheBoolean( boolean[] b ){
b[0] = true;
}
// Call:
boolean[] b = new boolean[1];
changeTheBoolean( b );
Related
I am coming from Java and learning Python, now. I try to understand the concept of class members in Python.
Here is an example program in Java:
class Hello {
int x = 0;
void ex() {
x = 7;
}
public static void main(String args[]) {
Hello h = new Hello();
System.out.println(h.x);
h.ex();
System.out.println(h.x);
} }
That is what I did in Python, following some examples I found:
class Hello:
def __init__(self) :
self.x = 0
def ex(self):
self.x = 7
h = Hello()
print(h.x)
h.ex()
print(h.x)
Both programs return:
0
7
Here are my questions:
Is the Python Code correct?
The programming style of Python appears to me to be more compact, compared to Java. So I am wondering, WHY does Python require the passing of a "self" -- Parameter.
At this point Python seems to be more "complex" than Java. Or is there a way to remove the "self" -- Parameter?
First, your python code is correct.
It's just a matter about how the languages is designed. Java uses a kind of automatic inference of a reference to the object. It can lead sometimes to strange behaviours for non-java experts:
private int a;
public int add(int a, int b){
return a+b; // what a will it use?
}
So, it's why in java there's the keyword this that can be used (but you're not forced) in order to solve that ambiguity.
The python team decided to force to use the word self (or any other word but I will explain later) to avoid that kind of problem. You cannot get rid of it. Though, java is still a more verbose language than python and the keyword self doesn't affect a lot that assumption.
However you're not obliged to use the "self" word as a reference to the current object. You can use any other word that would be the first parameter of your method (but it's a very bad practice).
Here, you can see two references that explain deeply why "self is here to stay":
http://www.programiz.com/article/python-self-why
http://neopythonic.blogspot.be/2008/10/why-explicit-self-has-to-stay.html
So in java the structure is generally
Class
private data (aka the "struct")
public data
constructors (__init__ in python)
functions etc
its very similar in python. same structure just for any functions working with the data you need to put self as an argument. where java it didn't have to take arguments.
Also it seems in python all data is public by default so you don't need to use getters and setters like in java.
personally I find a Python class more of a C-Struct with some added features, where java everything is thrown into a class.
For what's worth you can save a few line of codes when you have many fields, by using a library to remove the boilerplate. For example with pyfields:
from pyfields import field, make_init
class Hello:
x = field(default=0)
y = field()
__init__ = make_init()
h = Hello(y=10)
print((h.x, h.y))
yields
(0, 10)
You can even combine it with autoclass to get several features out of the box:
from autoclass import autoclass
from pyfields import field
#autoclass
class Hello:
x = field(default=0)
y = field()
h = Hello(y=1)
print(h)
assert h == {'x': 0, 'y': 1}
print(dict(h))
yields
Hello(x=0, y=1)
{'x': 0, 'y': 1}
See documentation for details. I'm the author by the way ;)
2.)Python is a high level language. where java is more mid-high im guessing. kind of new to java.
python goes by white space, where java requires more formatting.
3.) the self parameter can be removed. replace with whatever you want to call it.
This question is probably as old as the hills. Nevertheless, after reading lots of articles and forums I still don't see a good solution to my problem.
I have to transfer some Monte Carlo simulation programs from C++ to Java. The problem is that it heavily relies on passing variables by reference in functions, like:
void make_step(int &a, int &b, double &c) {
a++;
b += a;
c *= 1.1;
}
There is no passing by reference in Java, as well as possible analogs, like multiple return values or nested functions. Solutions, which I have read on this site, usually involve encapsulation of primitive types into objects. Alternatively - break functions to single-return ones. However, in my case it results in too long and complicated code (few lines of C++ code grow to almost pages in Java). Also, since these algorithms are hard to debug, I want to avoid dramatical changes in code while porting.
What I do now is substituting of all primitive type variables with arrays of length 1 (which are objects and can be modified inside functions). But it doesn't look like very elegant solutions. Does anyone have better ideas?
If you want the parameters to be "in-out" variables, they have to be object references.
With Mutable Wrappers
You can use mutable wrappers but this will require you to slightly modify your existing code (the algorithm):
class Int {
int v;
}
class MDouble {
double v;
}
void make_step(Int a, Int b, MDouble c) {
a.v++;
b.v += a.v;
c.v *= 1.1;
}
With Local Variable Copies
If you want to keep your original code, you can create local variable copies of the wrapped parameters, and you can use those without having to modify your code.
At the end of your method (before return) copy back the local variables into the wrappers and you're done. A tip for this is to use a try-finally block so your local variables will get copied back into the wrappers no matter how or where your method returns:
void make_step(int[] aa, int[] bb, double[] cc) {
int a = aa[0];
int b = bb[0];
double c = cc[0];
try {
// all your original code comes here
a++;
b += a;
c *= 1.1;
} finally {
aa[0] = a;
bb[0] = b;
cc[0] = c;
}
}
There are few options:
Wrap all parameters in an object. The simple version indeed makes the program longer, but if you can wrap the entire algorithm in an object then those parameters become the object members.
Use mutable integers (objects) - either Java's AtomicInteger which has get()/set() methods, or the commnos-lang version
There are mutable Integer and Decimal classes out there you can use those to pass by reference. Check out Apache Commons libraries here
When writing same logic from c++ to java
Rely more on .equals and comparators over == >< for comparisions
Use member variables and for local variable return the updated objects back to the called methods to get the changes.
You can use "atomic references" to wrap your object in a reference.
There are atomicXXX classes for most basic types as well. These will work similarly to normal references aside from the overhead of creating them in the first place.
Arrays of length 1 are just as a solution, but if you dislike the syntax or appearance of them, this is the only other solution that I know of that can mimic the same behavior without a general refactor.
In python you can do this:
def f():
return 1, 2, 3
(foo, bar, baz) = f()
Is there an equivalent in java?
tl;dr: No, there isn't such a thing in Java.
You can assign initial values to variables like this:
int foo = 1, bar = 2;
But if your want (1, 2, 3) to be the result of a method call, this is not possible in Java. Java does not allow returning multiple values.
Python allows this:
def foo():
return 1, 2, 3
a, b, c = foo()
The main point, why this does not work in Java is, that the left hand side (LHS) of the assignment must be one variable:
Wrapper wrapper = WrapperGenrator.generateWrapper();
You can not assign to a tuple on the LHS as you can in Python.
If you want (1,2,3) to be the result of a method call, you can use an array:
int[] arr = {1,2,3};
I realize this is an old post, but I could point out a way that comes somewhat close to this.
Using the OP's example (This could obviously use multiple types instead of three ints, but I'm going with the original example),
class Trip{ int foo;int bar;int baz;} // After building this class, have your editor create a constructor for you!
public Trip() {
return new Trip(1,2,3);
}
Trip t = f()
Now at this point I realize you haven't actually ASSIGNED this to three local variables (or member variables) as you would have liked, however you do have a local variable you can use as though you had... like:
t.foo * t.bar + t.baz;
The advantages here are that this is quite terse, hardly more work than the python example and safer/clearer/easier to read; as is I'd be really happy with this!
Perhaps more important though is that as you go on you will realize that this mini-class should have been a real class all along since the values are going to be somewhat associated since they are from the same function!
You can change what you have to a real class with simple editor refactors--replace member access with getter/setter, make members private, extract the class into it's own file and you have a full class!
Chances are that you'll eventually figure out that your original function f() should have been a member (or constructor) of this class in the first place!
By the way, the disadvantage is that this will fully trigger some Java programmers that don't understand that rules were meant to be broken--if you have old coders who are insistent on stuff that seems pedantic (rule-obsessed) it's best not to try this because it'll make their head explode (all over you, most likely).
As I noted in this other question, if your goal is specifically to return multiple values from a function, in Java 16+ you can accomplish something similar to this using a record type:
record FooResult(int a, int b, int c) { }
FooResult produceFoo() {
return new FooResult(1, 2, 3);
}
/* ... */
var f = produceFoo();
System.out.println(f.a + "," + f.b + "," + f.c);
This will let you return any set of types, with named fields, at the expense of having to add a line to declare the record. This won't really help with assignments like (i, j) = (j, i) however.
I am trying to learn a java-based program, but I am pretty new to java. I am quite confusing on the following two lines of java code. I think my confusion comes from the concepts including “class” and “cast”, but just do not know how to analyze.
For this one
XValidatingObjectCorpus<Classified<CharSequence>> corpus
= new XValidatingObjectCorpus<Classified<CharSequence>>(numFolds);
What is <Classified<CharSequence>> used for in terms of Java programming? How to understand its relationships with XValidatingObjectCorpusand corpus
For the second one
LogisticRegressionClassifier<CharSequence> classifier
= LogisticRegressionClassifier.<CharSequence>train(para1, para2, para3)
How to understand the right side of LogisticRegressionClassifier.<CharSequence>train? What is the difference between LogisticRegressionClassifier.<CharSequence>train and LogisticRegressionClassifier<CharSequence> classifier
?
These are called generics. They tell Java to make an instance of the outer class - either XValidatingObjectCorpus or LogisticRegressionClassifier - using the type of the inner object.
Normally, these are used for lists and arrays, such as ArrayList or HashMap.
What is the relationship between XValidatingObjectCorpus and corpus?
corpus is just a name given to the new XValidatingObjectCorpus object that you make with that statement (hence the = new... part).
What does LogisticRegressionClassifier.<CharSequence>train mean?
I have no idea, really. I suggest looking at the API for that (I think this is the right class).
What is the difference between LogisticRegressionClassifier.<CharSequence>train and LogisticRegressionClassifier<CharSequence> classifier?
You can't really compare these two. The one on the left of the = is the object identifier, and the one on the right is the allocator (probably the wrong word, but it is what it does, kind of).
Together, the two define an instance of LogisticRegressionClassifier, saying to create that type of object, call it classifier, and then give it the value returned by the train() method. Again, look at the API to understand it more.
By the way, these look like wretched examples to be learning Java with. Start with something simple, or at least an easier part of the code. It looks like someone had way too much fun with long names (the API has even longer names). Seriously though, I only just got to fully understanding this, and Java was my main language for quite a while (It gets really confusing when you try and do simple things). Anyways, good luck!
public class Sample<T> { // T implies Generic implementation, T can be substituted with any object.
static <T> Sample<T> train(int par1, int par2, int par3){
return new Sample<T>(); // you are calling the Generic method to return Sample object which works with a particular type of generic object, may it be an Integer or a CharSequence. --> see the main method.
}
public static void main(String ... a)
{
int par1 = 0, par2 = 0, par3 = 1;
// Here you are returning Sample object which works with a sequence of characters.
Sample<CharSequence> sample = Sample.<CharSequence>train(par1, par2, par3);
// Here you are returning Sample object which works with Integer values.
Sample<CharSequence> sample1 = Sample.<Integer>train(par1, par2, par3);
}
}
<Classified<CharSequence>> is a generic parameter.
LogisticRegressionClassifier<CharSequence> is a generic type.
LogisticRegresstionClassifier.<CharSequence>train is a generic method.
Java Generics Tutorial
I was playing with Java as I am planning to switch from C# to it for cross platform purposes. I have just noticed that it has a lot of methods that just do the same thing. And I just want to know why did they do that ?
An example, the Boolean class has two methods doing the same thing in addition to the constructor which does the same thing too.
Boolean b = new Boolean(true);
Boolean b = new Boolean("true");
Boolean b = Boolean.parseBoolean(true);
Boolean b = Boolean.parseBoolean("true");
Boolean b = Boolean.valueOf(true);
Boolean b = Boolean.valueOf("true");
And I can get the boolean value either by just calling the variable itself (b) or the method b.booleanValue(). Would anyone want to call a method getting the boolean value of a boolean although he can just call the variable itself ?
What is the point ?
new Boolean(true) and Boolean.valueOf(true) return Boxed primitives. Real objects that can be used in collections etc. from primitive boolean values.
Boolean.parseBoolean("true") returns the primitive boolean value.
btw,
Boolean b = Boolean.parseBoolean(true);
Boolean b = Boolean.parseBoolean("true");
are really mistakes. you are creating a primitive boolean and then auto boxing to Boolean.
You should use valueOf(true) or valueOf("true") instead.
So the real use of these methods would be
Boolean b = new Boolean(true); //really this should never be used **
Boolean b = new Boolean("true"); //really this should never be used **
boolean b = Boolean.parseBoolean(true);
boolean b = Boolean.parseBoolean("true");
Boolean b = Boolean.valueOf(true);
Boolean b = Boolean.valueOf("true");
** don't use this as you are just creating objects needlessly. Using valueOf allows for reusing existing Boolean objects. Since Booleans are immutable this is fine.
Sometimes you need to parse string to primitive Boolean.parseBoolean(*String*)
Sometimes you need to parse String to Boolean Boolean.valueOf(*String*)
Sometimes you need not create new object. Better avoid using new
Sometimes you need the Boolean object instead of primitive Boolean.valueOf(*boolean*)
These are not same need.
They are not really duplicate methods/constructors, if you notice difference between true and "true". true means primitive type boolean in Java but "true" means a java.lang.String object that has a value "true".
you missed the funniest one
Boolean.getBoolean("true")
What is the point ?
Well, the point is that some of those alternatives are useful, and some are old methods left over from the first version of Java.
(The original version of Java was released in a rush, and there were a few design mistakes / inconsistencies in the APIs. However, the overarching requirement to maintain backwards compatibility meant that it was impossible to correct them. In cases where the mistakes were positively harmful, the relevant methods have been marked as "deprecated" to warn programmers not to use them. In harmless cases like this where methods are simply redundant, things have been left unchanged.)
Note that they are not the same; one of your lines:
Boolean b = Boolean.parseBoolean(true);
would give a syntax error (at least according to the Java 6 api).
Boolean.valueOf(true) and new Boolean(true) are different functions in that new Boolean(true) would create a new object and Boolean.valueOf(true) returns a stored Boolean object.
The signature of Boolean.parseBoolean returns a primitive boolean. Before Java 5 you needed Boolean.valueOf to convert it to an object form. After Java 5 the system will do that automatically, but (a) Java decided it wanted explicit forms of the autoboxing (and thus added Integer.valueOf and such) and (b) methods of Java are never deleted even when they become obsolete. In many cases that is a source of duplication itself (such as when they reorganized collections way back in Java 2 but old collection classes had methods added to match the new system leading to duplication).
Boolean is a type that herits from Object, in opposit to b.booleanValue() it returns a primitive type boolean.
so the difference is that the first is an object and the second is a primitive type.
You listed one that doesn't exist, and you incorrectly specified the return type of parseBoolean. The list is actually:
Boolean b = new Boolean(true);
Boolean b = new Boolean("true");
boolean b = Boolean.parseBoolean("true");
Boolean b = Boolean.valueOf(true);
Boolean b = Boolean.valueOf("true");
(4) is redundant with (1) and (5) is redundant with (2). Except two are constructors and two are methods. I suspect having that functionality from methods rather than from a constructor might be useful to something (factories?).
java.lang.Boolean