I'm a bit confused about information passing to methods in Java. I'm currently studying Java basics on Oracle website and while most things I understand with no problem, some things aren't clear enough to me.
https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html
Here is where I'm having doubt. When they write the following code...
public void moveCircle(Circle circle, int deltaX, int deltaY) {
// code to move origin of circle to x+deltaX, y+deltaY
circle.setX(circle.getX() + deltaX);
circle.setY(circle.getY() + deltaY);
// code to assign a new reference to circle
circle = new Circle(0, 0);
}
What do they mean by circle = new Circle(0, 0);? Is it creating a new Cicle object or what? I think what confuses me is how the object parameter is used inside the method declaration.
Can someone explain to me clearly what Passing reference data types is about?
Start with a simpler example:
public class Main {
public static void main(String... args) {
int x = 7;
add(x);
System.out.println(x);
}
public static void add(int y){
y = 10;
}
}
What do you expect this code to print out?
It prints out 7 because even though we're reassigning the parameter received by the add() function, that doesn't affect the original value passed into the function. The x variable in the main() method is still 7.
The example code is just showing you a more complicated example of that with Objects instead of primitives. The lesson you're supposed to learn is that reassigning parameters in a function does not affect their original values.
These changes will persist when the method returns. Then circle is assigned a reference to a new Circle object with x = y = 0. This reassignment has no permanence, however, because the reference was passed in by value and cannot change.
Read the last paragraph carefully.
You are able to modify the attributes of the referenced circle, but if you assign the variable a new reference, no changes were made to the original object. It only tells myCircleto refer to a newly created object. And this object gets immediately garbage collected after the method goes out of scope.
Explanation for the two questions you asked:-
circle = new Circle(0, 0) means that we are assigning values to the constructor of Circle object .
Yes this is creating new circle object by passing values to the reference variable circle.
Hope it helps!
Related
If I have a class like such:
public class First {
int x = 1;
}
and a second class:
class Main {
public static void main(string args[]) {
First someObject = new First();
someObject.x = 2;
}
}
is only someObject.x equal to 2 or would any object of class First being created afterwards be initialized with it's x attribute being equal to 2. If not, how would one change the default value of x for any object being made of class First?
First of all, you need to read about what "pass by reference" really means. (For example, here.) Passing semantics refer to what happens to arguments in a procedure/method/subroutine/function call. In your example, there is no "passing" going on at all when you are assigning to the x field.
So your
In Java are object attributes passed by reference to other classes
is a meaningless and/or irrelevant question. (But the plain answer is that Java does not support "pass by reference". Period.)
As for what I think you are trying to ask, lets start with some facts:
The Field class declares x as an instance field.
Each instance of First has its own "copy" of the x field.
The x field is part of one and only one instance. It is not shared with any other First instance.
This is irrespective of the declared type of x ... modulo that a field whose declared type is a reference type will contain a reference to an object rather than the object itself. (But int is not a reference type.)
The new First() expression creates a new instance of the First class that is distinct from all other (past, present or future) instances of First and returns its reference.
So, in this code:
First f1 = new First();
First f2 = new First();
f1.x = 2;
System.out.println(f2.x); // prints 1.
We have two instances of First that f1 and f2 refer to (point at) distinct First instances. If you change the x field of one instance does not change the x field of the other intance. They are different fields.
However, if you had declared x as static in First, then x is no longer a distinct field for each First instance. It is now a shared by all instances of First.
As an addendum, how would one change the default value of x in the First class such that any new instance made afterwards would have a difference value of x to start?
Firstly int x = 1; in First is not defining a "default" value in the sense that Java uses that term. It is actually an initialization. (A default value is what you see if you DON'T have an initialization.)
If you wanted to implement application specific default value that is common to all instances of First and that can be changed retrospectively, you need to implement it in Java code. Maybe something like this:
public class First {
static int defaultX = 1;
private int x;
private boolean xSet = false;
public int getX() {
return xSet ? x : defaultX;
}
public void setX(int x) {
this.x = x;
this.xSet = true;
}
}
Note that in order to implement the defaulting behavior we want, we have to hide the x field (make it private) and implement the desired behavior in the getter and setter methods.
This question already has answers here:
Deleting an object in java?
(7 answers)
Closed 1 year ago.
class Point{
int x;
int y;
Point (int x,int y)
{
this.x=x;
this.y=y;
}
}
public static void main(String args[])
{
Point p =new Point (2,3);
Point p1 = new Point(2,4);
}
If I create two objects of this Point class and then again create another object of the Point class then will the last Point object that is p will get delete or will remain ??
In Java, as in many other languages, there is something called "object scope", which actually represents the lifecycle of an object.
In particular, if you instantiate an object inside a specific block of code, that represents the scope of your object, and your reference will be valid as long as the block is executed.
After reaching the first line outside that block, your reference is taken in charge by the "Gargage collector", which basically is the mechanism in Java responsible for cleaning up the memory from all those objects which don't have any reference inside your program and, thus, you don't need it anymore.
In your particular case, as there are the only two stetements of program, both references will be valid for the entire program.
However, there is a scenario in your simple program which can make you loose one reference see this piece of code:
public class Point{
int x;
int y;
Point (int x,int y)
{
this.x=x;
this.y=y;
}
}
public static void main(String args[])
{
Point p =new Point (2,3);
p = new Point(2,4);
}
As you see, because I have assigned the second object Point to the same reference p, the first one will be lost and, thus, automatically handed over to the garbage collector to be freed from the memory.
However, the above code was just one of the example of the technique you can use to make an object get taken in charge by the Garbage collector. I suggest that you have a look at the answer Deleting object in Java? where you will find more examples and different techniques.
Java do remove object whenever they are not need anymore.
In this case as long as your program runs inside the main method, the Point objects will not be removed.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 5 years ago.
public class SeamCarving {
public static Seam carve_seam(int[][] disruption_matrix) {
int[][] original = disruption_matrix;
int[][] weighted_matrix = disruption_matrix;
SeamCarving s1 = new SeamCarving();
weighted_matrix = s1.buildMatrix(disruption_matrix);
....
}
In the above code I have a static method carve_seam. The method takes a matrix. That input is saved in a matrix variable called original. A calculation is performed on the matrix and that is also saved as a variable called weighted_matrix. Both are needed.
Since its in a static method, a new object of the class is made and it is called from that "s1.buildMatrix"
However, that line is doing something that is over my head. This is because afterwards, not only is weight_matrix changed (correctly from the buildMatrix method) but original is also changed to the same exact thing! How does this happen???
First thing you need to understand here is that all the three reference matrix, are referring to the same object you have passed as the input (disruption_matrix object). This is the reason why also the original and weighted_matrix are being changed.
In the first line,
int[][] original=disruption_matrix;
refers to the same object in disruption_matrix.
Then on the next line,
int[][] weighted_matrix=disruption_matrix;
refers to the same old object as well. So, you do not need to reach the line,
weighted_matrix = s1.buildMatrix(disruption_matrix);
to see that both original and weighted matrix have been changed. Actually the they have been changed when you have done the calculation to the disruption_matrix itself.
This situation is quite similar to a something like, where,
int a=10;
int b=a;
int c=a;
So, not only 'a' but also 'b' and 'c' will have their value assigned to 10.
In a OOP manner, where such same object is being assigned to different references, once a change has been made to the object through a single reference no matter that you're accessing the object through a different reference, the object has been changed.
For an example let's take this simple class,
Class A{
int val=10;
}
now, in some method we create an object and assign it to references,
A a=new A();
a.val=20;
A b=a;
b.val=30;
A c=a;
c.val=40;
As for the above code, an object is created under the reference called 'a'. In the next line, the value 'val' is accessed through that reference and has been changed from 10 to 20.
Then, the reference 'b' has been declared and it is initialized and pointed to the same object which 'a' is holding. Then in the next line, the value of that object (val) is changed again 20 to 30, but this time through 'b' instead of the reference 'a'.
Same goes to the next three lines where the value of the object is being changed from 30 to 40 through the reference 'c'.
So finally what will be the output?
System.out.println(a.val);
System.out.println(b.val);
System.out.println(c.val);
It is obviously going to give you the output,
40
40
40
This is the concept you are missing here (Pass by value and pass by reference).
In Java, Arrays are technically objects and not primitives, even for arrays of primitive types. Whenever you pass an argument to a method as an object, Java passes it as a reference; the values of the original argument change because all variables you have created are "referring" to the same object. This, however, is not the case with primitives, which are passed by value.
I suggest that whenever you need to make a matrix off of another you use the following utility method:
public static int[][] copyMatrix(int[][] original) {
int[][] copy = new int[original.length][];
for(int x = 0; x < copy.length; x++) {
copy[x] = new int[original[x].length];
for(int y = 0; y < copy[x].length; y++) {
copy[x][y] = original[x][y];
}
}
return copy;
}
At the end, your code would look like this:
public class SeamCarving {
public static Seam carve_seam(int[][] disruption_matrix) {
// no need to make an "original" variable anymore,
// since disruption_matrix already stands for it
int[][] weighted_matrix = copyMatrix(disruption_matrix);
SeamCarving s1 = new SeamCarving();
weighted_matrix = s1.buildMatrix(disruption_matrix);
....
}
}
Keep in mind that this implementation copies the arrays but not the objects. This will solve your problem when working with primitives like int but not with mutable objects.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
I have a list of Cell object that represent a board game inside the board class.
Cell boardGame[][] = new Cell[8][8];
I needed a temporary cell to try the player move on him and compare it to the other cells, so I though that I could use a java pass-by-value to do it.
test(board.boardGame);
board.printBoard();
private static void test(Cell[][] boardGame) {
Cell c = new Cell((new Soldier(ChessPiece.QUEEN, Color.WHITE)), 7, 4);
boardGame[7][7] = c;
}
I read some post about java here, but apparently I still didn't catch it 100%.
I expected to see only one white queen on the board, but I saw two.
I know that if you pass a reference you can change its values, but I though that if I would pass the array itself its members won't be modified unless I would execute a return.
Please help me to understand this subject better.
Thanks
Edit:
I think I don't understand when it called attributes and where it doesn't.
I though the different it if you are call "new" or not.
When its part of another object it called attribute right? but every object can be created as part of another object. I can create a new string in dog class and then create the dog class in the animal class and then create it in another class. So only the top class is in the stack?
For exemple:
public class Board { //fake class
int num= 0;
public void test(int i){
i = 1;
}
}
and on another class:
public class Main {
static void outsideTest(Board board){
board.num = 1;
}
public static void main(String[] args) {
Board board = new Board();
System.out.println(board.num);
board.test(board.num);
System.out.println(board.num);
outsideTest(board);
System.out.println(board.num);
}
}
Now I didn't understand why on test() method the num didn't change and on outsideTest() the num change, num as been created in the heap because its part of the board object, so its need to be changed on both cases no?
The best and least confusing way to remember it is as follows: Java passes everything by value, that includes the references. :)
When you have a variable:
Object a = new Object();
you don't actually have an object stored in a. What you have is a reference to an object somewhere in memory.
Likewise when you call a method on an object:
String b = a.toString();
you don't do that. What you call is a method that uses the data of the referenced object as its context.
So when you pass an object as an argument
System.out.println(b);
You don't pass the whole object. You pass the reference and that reference is passed by value.
edit:
If the reference were not passed by value, but by reference, you could do something like this, which fortunately you can't.
public void swap(Object a, Object b){
Object swap = a; a = b ; b = swap;
}
String a = "a";
String b = "b";
swap(a,b);
// would print "b a" if references were
// passed by reference but instead prints
// "a b" as they're passed by value.
System.out.println(a + " " b);
The reference to the object is passed by value, which means that
boardGame = new Cell[8][8];
does not do any harm, but changing anything you get from boardGame does.
Java is essentially always "pass-by-value".
Caveat: It passes the value stored in the memory for the variable.
For primitive data types, the memory is allocated in stack space, whereas for objects reference memory is allocated in stack space but the object itself is created in heap. Similar can be stated for arrays too though they are not exactly objects in a strong sense.
Diagrams below would make it clearer.
Your Cell object 2D array should seem something like anObjectArrayVar (not exactly as the ref in the diagram pointing to the objects should now be pointing to the rows and we would need another level of allocation in heap in between ref and objects for each row (a set of cells refering to the objects).
So, when you pass boardGame, the value stored in the stack is passed that stores the reference to the array of objects (just like the value stored in the anObjectArrayVar). If say the list of refs is stored in location numbered 50 then anObjectArrayVar would have stored that and it passes that value to the test method when we call it. In such a scenario the test method wont be able to goto memory location anObjectArrayVar and change its value (to say 100) as it has only a copy of the value but it could easily change what it refers to(directly or indirectly) like the values in ref or the next level (and add new objects as in your case adding a new cell with queen) or the objects pointed to by them and those changes would reflect through out the program!
I would also like to draw your attention to the fact that the code
boardGame[7][7] = c;
would replace the current cell (as well as the soldier currently in it) which would create major issues if there was originally a soldier in that place at that point in the game. The game state would actually change.
As a suggestion (given the limited knowledge about your design) I would say at least save the cell in some other value in test method before replacing it.
Cell old = boardGame[7][7];
//now do all your operations
boardGame[7][7] = old;//just before returning from the function
I know Java doesn't have pointers, but I heard that Java programs can be created with pointers and that this can be done by the few who are experts in java. Is it true?
All objects in Java are references and you can use them like pointers.
abstract class Animal
{...
}
class Lion extends Animal
{...
}
class Tiger extends Animal
{
public Tiger() {...}
public void growl(){...}
}
Tiger first = null;
Tiger second = new Tiger();
Tiger third;
Dereferencing a null:
first.growl(); // ERROR, first is null.
third.growl(); // ERROR, third has not been initialized.
Aliasing Problem:
third = new Tiger();
first = third;
Losing Cells:
second = third; // Possible ERROR. The old value of second is lost.
You can make this safe by first assuring that there is no further need of the old value of second or assigning another pointer the value of second.
first = second;
second = third; //OK
Note that giving second a value in other ways (NULL, new...) is just as much a potential error and may result in losing the object that it points to.
The Java system will throw an exception (OutOfMemoryError) when you call new and the allocator cannot allocate the requested cell. This is very rare and usually results from run-away recursion.
Note that, from a language point of view, abandoning objects to the garbage collector are not errors at all. It is just something that the programmer needs to be aware of. The same variable can point to different objects at different times and old values will be reclaimed when no pointer references them. But if the logic of the program requires maintaining at least one reference to the object, It will cause an error.
Novices often make the following error.
Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed.
What you probably meant to say was:
Tiger tony = null;
tony = third; // OK.
Improper Casting:
Lion leo = new Lion();
Tiger tony = (Tiger)leo; // Always illegal and caught by compiler.
Animal whatever = new Lion(); // Legal.
Tiger tony = (Tiger)whatever; // Illegal, just as in previous example.
Lion leo = (Lion)whatever; // Legal, object whatever really is a Lion.
Pointers in C:
void main() {
int* x; // Allocate the pointers x and y
int* y; // (but not the pointees)
x = malloc(sizeof(int)); // Allocate an int pointee,
// and set x to point to it
*x = 42; // Dereference x to store 42 in its pointee
*y = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
*y = 13; // Dereference y to store 13 in its (shared) pointee
}
Pointers in Java:
class IntObj {
public int value;
}
public class Binky() {
public static void main(String[] args) {
IntObj x; // Allocate the pointers x and y
IntObj y; // (but not the IntObj pointees)
x = new IntObj(); // Allocate an IntObj pointee
// and set x to point to it
x.value = 42; // Dereference x to store 42 in its pointee
y.value = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
y.value = 13; // Deference y to store 13 in its (shared) pointee
}
}
UPDATE: as suggested in the comments one must note that C has pointer arithmetic. However, we do not have that in Java.
As Java has no pointer data types, it is impossible to use pointers in Java. Even the few experts will not be able to use pointers in java.
See also the last point in: The Java Language Environment
Java does have pointers. Any time you create an object in Java, you're actually creating a pointer to the object; this pointer could then be set to a different object or to null, and the original object will still exist (pending garbage collection).
What you can't do in Java is pointer arithmetic. You can't dereference a specific memory address or increment a pointer.
If you really want to get low-level, the only way to do it is with the Java Native Interface; and even then, the low-level part has to be done in C or C++.
There are pointers in Java, but you cannot manipulate them the way that you can in C++ or C. When you pass an object, you are passing a pointer to that object, but not in the same sense as in C++. That object cannot be dereferenced. If you set its values using its native accessors, it will change because Java knows its memory location through the pointer. But the pointer is immutable. When you attempt to set the pointer to a new location, you instead end up with a new local object with the same name as the other. The original object is unchanged. Here is a brief program to demonstrate the difference.
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
System.out.println("Expected # = 0 1 2 2 1");
Cat c = new Cat();
c.setClaws(0);
System.out.println("Initial value is " + c.getClaws());
// prints 0 obviously
clawsAreOne(c);
System.out.println("Accessor changes value to " + c.getClaws());
// prints 1 because the value 'referenced' by the 'pointer' is changed using an accessor.
makeNewCat(c);
System.out.println("Final value is " + c.getClaws());
// prints 1 because the pointer is not changed to 'kitten'; that would be a reference pass.
}
public static void clawsAreOne(Cat kitty) {
kitty.setClaws(1);
}
public static void makeNewCat(Cat kitty) {
Cat kitten = new Cat();
kitten.setClaws(2);
kitty = kitten;
System.out.println("Value in makeNewCat scope of kitten " + kitten.getClaws());
//Prints 2. the value pointed to by 'kitten' is 2
System.out.println("Value in makeNewcat scope of kitty " + kitty.getClaws());
//Prints 2. The local copy is being used within the scope of this method.
}
}
class Cat {
private int claws;
public void setClaws(int i) {
claws = i;
}
public int getClaws() {
return claws;
}
}
This can be run at Ideone.com.
Java does not have pointers like C has, but it does allow you to create new objects on the heap which are "referenced" by variables. The lack of pointers is to stop Java programs from referencing memory locations illegally, and also enables Garbage Collection to be automatically carried out by the Java Virtual Machine.
You can use addresses and pointers using the Unsafe class. However as the name suggests, these methods are UNSAFE and generally a bad idea. Incorrect usage can result in your JVM randomly dying (actually the same problem get using pointers incorrectly in C/C++)
While you may be used to pointers and think you need them (because you don't know how to code any other way), you will find that you don't and you will be better off for it.
Technically, all Java objects are pointers. All primitive types are values though. There is no way to take manual control of those pointers. Java just internally uses pass-by-reference.
Not really, no.
Java doesn't have pointers. If you really wanted you could try to emulate them by building around something like reflection, but it would have all of the complexity of pointers with none of the benefits.
Java doesn't have pointers because it doesn't need them. What kind of answers were you hoping for from this question, i.e. deep down did you hope you could use them for something or was this just curiousity?
All objects in java are passed to functions by reference copy except primitives.
In effect, this means that you are sending a copy of the pointer to the original object rather than a copy of the object itself.
Please leave a comment if you want an example to understand this.
As others have said, the short answer is "No".
Sure, you could write JNI code that plays with Java pointers. Depending on what you're trying to accomplish, maybe that would get you somewhere and maybe it wouldn't.
You could always simulate pointes by creating an array and working with indexes into the array. Again, depending on what you're trying to accomplish, that might or might not be useful.
from the book named Decompiling Android by Godfrey Nolan
Security dictates that pointers aren’t
used in Java so hackers can’t break out of an application and into the operating
system. No pointers means that something else----in this case, the JVM----has to
take care of the allocating and freeing memory. Memory leaks should also
become a thing of the past, or so the theory goes. Some applications written in
C and C++ are notorious for leaking memory like a sieve because programmers
don’t pay attention to freeing up unwanted memory at the appropriate time----not
that anybody reading this would be guilty of such a sin. Garbage collection
should also make programmers more productive, with less time spent on
debugging memory problems.
Java reference types are not the same as C pointers as you can't have a pointer to a pointer in Java.
you can have pointers for literals as well. You have to implement them yourself. It is pretty basic for experts ;). Use an array of int/object/long/byte and voila you have the basics for implementing pointers. Now any int value can be a pointer to that array int[]. You can increment the pointer, you can decrement the pointer, you can multiply the pointer. You indeed have pointer arithmetics!
That's the only way to implements 1000 int attributes classes and have a generic method that applies to all attributes. You can also use a byte[] array instead of an int[]
However I do wish Java would let you pass literal values by reference. Something along the lines
//(* telling you it is a pointer)
public void myMethod(int* intValue);
You can, but not completely. You can't directly access pointers but you can have lists with variables that point to the same location. I came across a way by accident a few years ago.
I'm not sure why but in Java when you set a list to equal another list, rather than copying all the information, a pointer to the original list is made. I'm not sure if it applies to all forms of lists, but it has for the ones I have tested so far. I believe arrayList also has the function clone(), to circumvent this, if you wanted a proper seperate list.
int[] example
public class Main {
public static void main(String[] args){
int[] alpha = new int[] {1,2,3};
int[] beta = alpha;
beta[0]=9;
beta[1]=9;
beta[2]=9;
System.out.println("alpha: " + alpha[0] + ", " + alpha[1] + ", " + alpha[2]);
System.out.println("-beta: " + beta[0] + ", " + beta[1] + ", " + beta[2]);
}
}
arrayList example
import java.util.ArrayList;
public class Main {
public static void main(String[] args){
ArrayList<Integer> alpha = new ArrayList<>();
alpha.add(1);
alpha.add(2);
alpha.add(3);
ArrayList<Integer> beta = alpha;
beta.add(4);
beta.set(0, 5);
System.out.println("alpha: " + alpha.toString());
System.out.println("-beta: " + beta.toString());
}
}
All java objects are pointer because a variable which holds address is called pointer and object hold address.so object is pointer variable.
java can easily has pointer by knowing that the array name is pointer to the the first index. this why when we pass array to function we don't write its square brackets. because array is reference
public class Main
{
public static void func ( int ptr1[] , int ptr2[] )
{
int temp;
temp = ptr1[0];
ptr1[0] = ptr2[0];
ptr2[0] = temp;
}
public static void main(String[] args) {
int x = 5; int y = 8;
// in c language
// int *p = &x; int *q = &y;
// in Java
int p[] = new int[1];
int q[] = new int[1];
p[0] = x; // same as pointer
q[0] = y; // same as pointer
func( p , q ); // passing address ( refrence )
System.out.println( " After Swap " );
System.out.println( "x = " + p[0] + " " + "y = " + q[0] );
}
}