Understanding constructors (very simple code) - java

public class HelloWorldV3
{
//default constructor
HelloWorldV3()
{
}
//print two lines of text
public void printTwoLines( )
{
System.out.println("Hello, Virtual World!");
System.out.println("It is a great day for programming.");
}
//main method
public static void main(String [] args)
{
HelloWorldV3 hello = new HelloWorldV3( );
hello.printTwoLines();
}
Hi, I am beginning to learn about constructors, and I am having trouble understanding some code. In the program above, I know that a constructor was created, but it is empty. The printTwoLines() function prints the two lines, and the main method uses the constructor to call the function. I had questions about why there needs to be the "HelloWorldV3 hello = new HelloWorldV3();" line, and what would happen if there was actually something in the constructor.

The:
HelloWorldV3 hello=new HelloWorldV3();
line makes a variable called hello. Hello is a different type of variable than what you are probably used to, and doesn't store a number, or integer, or anything like that, but an object (really the location of the object, but don't worry about that for now). You could also write it as :
HelloWorldV3 hello;
hello=new HelloWorldV3();
just as you would write:
int i;
i=5;
You can then access either the hello variable or the i variable.
As for the second part of your question, anything in the constructor would be called when the code:
new HelloWorldV3();
is executed. So you could put some code inside the constuctor like this:
public HelloWorldV3() {
System.out.println("In the constuctor");
}

It's just that you allocating the space with new operator for your HelloWorldV3 object.
It's always good to define state in constructor. By state i mean is, if you have say int field, you could initialize it to say default value that might be appropriate when you create your object (say to value 10)

The constructor will initilize your object "hello" of type "HelloWorldV3".
If there is a code in the constructor, it will be executed when calling "new HelloWorldV3( )" in your first line of code of the method. So it will be executed before the method "printTwoLines".
I hope I was clear :)
Thanks.

You need the line
HelloWorldV3 hello = new HelloWorldV3( );
because that is what creates an instance (object) of the class HelloWorldV3, allowing you to call its methods and access its fields (if any).
Java does some things behind the scenes to instantiate an object, and the concept of a constructor exists to allow you to specify code to execute (mostly initialization stuff) when Java is creating an instance of the class.
If there was code in the constructor, that code would execute when the line
HelloWorldV3 hello = new HelloWorldV3( );
executes.
To answer your question with a question, if there wasn't that line, then how would you ever call the printTwoLines() method?

Related

How do I create an object within method sending reference as a parameter [duplicate]

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.

Create an inline object and pass as parameter

Hi I come from Java where the following is valid:
System.out.println(new String("Hello World"));
is there a C++ equivalent to passing creating an object or pointer in the constructor and pass it as a parameter at the same time such as.
heap.insert(new Food);
Yes. For example
std::vector<Food> c;
c.emplace_back(constructor arguments for Food);
In general, it is most often the case that objects are not given to method as pointers.
If heap.insert takes a const reference :
void insert(const Food& val);
then you can use it with temporary or existing Food arguments, such as
heap.insert(Food{});
var auto foo = Food{constructor arguments};
heap.insert(foo);
heap.insert(Food(constructor arguments));
or in some cases even
heap.insert({constructor arguments});
heap.insert(new Food);
in of itself is valid C++ syntax. It constructs a new instance of the Food class, and passes it to heap's insert() method.
However, the key fundamental difference you will need to learn when transitioning from Java to C++ is that your C++ application is completely responsible for managing all object's lifetimes. In Java you don't need to think about it. Once an object is no longer referenced anywhere, at some point it'll get destroyed by Java's garbage collector.
C++ makes you responsible for managing each object's lifetime. Whenever your application does not need the object that you constructed here with the new operator, it should be deleted, otherwise you're going to leak memory.
To summarize:
heap.insert(new Food);
is just half the story. The new operator will construct your new class instance, and your heap object's insert() method, presumably, stores the pointer to the new class instance, in some fashion. Somewhere, you will then need to delete that class instance, sooner or later.
Yes. You have to define a class, a constructor for it that accepts parameters, then a function that accepts instances of that class and that's all.
Eventually, add to the class definition a proper copy constructor or pass it by reference.
It follows an example:
struct S {
S(int x) { this->x = x; }
int x;
};
void fn(S s) { }
void cfn(const S &s) { }
int main() {
fn(S{42});
cfn(S{42});
}
Be aware that using new in such a case is one of the easiest ways to incur in a memory leak, so pay attention!!
The examples you gave are too easy.
cout << string("hello World");
// not necessary to contruct a string, but to show that it can be done on the spot
heap.insert(Food()); // construct a Food on the spot...
But in general, if you are talking about anonymous classes and similar things in Java, C++ has this stuff, and it has also the lambda concept which is very powerful ;)
If the function parameter is by value or by const reference, and the type you are passing can be used to construct the object, you can pass it directly. For example:
void print(const std::string& str);
int main()
{
print("Hello world");
}
std::string has a constructor which can accept the string literal, and therefore the code compiles, creating a temporary string object, equivalent to:
print(std::string("Hello world"));
If the constructor takes multiple parameters, you can create a temporary object directly in the function call. For example:
void myfunc(const MyClass& c);
myfunc(MyClass(param1, param2));
In Java new objects are creating using new. In C++, new is not required to create a new object, and should be avoided as much as possible, because it makes it harder to avoid memory leaks. This is one of the most common mistakes programmers coming from Java make.
std::string text;
MyClass c;
c.do_something();
This code is totally valid. text and c are valid objects.
std::string *text = new std::string();
MyClass *c = new MyClass();
c->do_something();
delete text;
delete c;
This code is also valid*. But it takes more typing, and if you forget to delete them, you will get a memory leak.
*Edit: Actually it is not exception safe! All the more reason to avoid new!

array as instance variable passed as parameter

I have a class with an array as an instance variable/field, which is passed through from another class to the first method in this one.
I was under the impression that I should also be able to access it from another method without also passing it to that method but when I try, I get an NPE.
Here's the code:
public class PLoop {
// instance variable
public Memory[] memList;
// method 1
public void memPass(Memory[] memLocList) {
memList = memLocList;
System.out.println(memList.length);
}
// method 2
public void accessArray() {
System.out.println(memList.length);
}
}
When the first method is called I get an integer printed to the console representing the length of the array but when the second method is called it's NPE, suggesting not the same array.
The second method is called by clicking a button on a GUI. The method associated with this button only has a call along the lines of:
PLoop.accessArray();
Can anyone tell from this what I'm doing wrong?
-EDIT-
The calls to these methods come from two different classes, each of which declares an instance of PLoop:
proc = new PLoop();
I strongly suspect that the instance you've called memPass on isn't the same instance you're later calling accessArray on.
It should be absolutely fine if you're using the same instance. (In particular, it's the value of the argument which will be stored, so it's not like memList can become null after not being null, just due to changes elsewhere.)
The code in the class you have shown looks fine, so if you are getting a NPEx then either the methods are being called out of sequence, or the second method call is being made on a different instance of PLoop to the first.
To check if the calls are being made on the same object or not, try printing out the value of this inside your methods and check if the values are the same:
System.out.println(this);
The Methods in your PLoop classes are not static
Still you are calling PLoop.accessArray();
Can u please tell what is the real Scenario?
Just like #Jon Skeet told the code seems to be fine.The only possibility is that you may be
executing them out of sequence or you may be messing up with memLocList after the first
method is called.

Can objects be passed by value rather than by reference in Java?

Let's consider the following code in Java.
package obj;
final class First
{
public int x;
public First(int x)
{
this.x=x;
}
}
final class Second
{
public Second(First o)
{
o.x=10;
}
}
final public class Main
{
public static void main(String[] args)
{
First f=new First(50);
Second s=new Second(f);
System.out.println("x = "+f.x);
}
}
In the above code, we are supplying a value 50 through the statement First f=new First(50); which is being assigned to a class member x of type int in the constructor body in the class First.
In the class Second, the object f of the class First is being passed through the statement Second s=new Second(f); and we are modifying the value of the instance variable x held in that object to 10 which will affect the original object f because in Java objects are always passed by reference and not by value.
In some specific situations, it may be crucial not to allow such changes to the original objects. Is there any mechanism in Java that may allow us to prevent such modifications? (that might allow us to pass objects by value)
No, the object isn't being passed at all in Second. The reference is being passed by value.
Java always uses pass-by-value, but the value of any expression is only ever a primitive type or a reference - never an object.
It sounds like you want to create a copy of an existing object, then pass a reference to that new object to the method (by value). Quite what constitutes a "copy" will depend on the data in the class. (You may be able to get away with a shallow copy, or you may need to go deeper etc.)
No, there aren't. I would say that your example is not a very good one: if you want to ensure that something doesn't change, don't provide ways to change it. Causing the change to be lost afterwards is misleading at best.
First f=new First(50);
Second s=new Second(f);
in first line you are create a reference variable of Object type First and in 2nd line it is pass to Class Second
So as Jon Skeet say in java "Java always uses pass-by-value, but the value of any expression is only ever a primitive type or a reference - never an object."
And if if u don't want to change the value of property then u must be pass new object of class First
Because if u have a reference of any class then u can change the property of that class ..
Or u can create a copy of that object which is at the end creating a new object of First Class

className.main(new String[]{"filename.txt"})?

I created a class that does some file parsing for me. I made it possible to be started as a standalone application, taking file name from command line.
Now I created another class, that needs to take advantage of what the first class is doing, and I tried to call its main method like this:
className.main(new String[]{"filename.txt"});
However, it seems that things aren't doing so fine, because I was getting some null pointer exceptions. When I inserted system.out.println(args[0]) to see what was going on, I got the reference to the resource, and not the string I was expecting.
Here is more code:
// this is from the class that is reffered as 'new one'
// Cal the maze solver now for out.txt
String[] outFile = new String[]{"out.txt"};
MazeSolver.main(outFile);
// this is part of the MazeSolver main method
public static void main(String[] args) {
if(args.length != 1) {
System.out.println("Usage: java MazeSolver ");
System.exit(0);
}
// this is the part where i tried to debug
System.out.println(args.toString());
// and this is the error message that i got in terminal
// [Ljava.lang.String;#63b9240e <---------------------------------------
//ROWCOUNT: 199
//Exception in thread "main" java.lang.NullPointerException
Do I need to create one more method, doing the exact same thing, but with different name?
Thanks
I'm just answering the part about printing an array of Strings:
System.out.println(args.toString());
This won't work, Array.toString() just returns an internal representation. You will want to use the helper method Arrays.toString(arr) in the Arrays class:
System.out.println(Arrays.toString(args));
Or, if you are dealing with a multi-dimensional array, use Arrays.deepToString(arr):
final Object[][] arr = new Object[3][];
arr[0]=new String[]{"a","b","c"};
arr[1]=new Integer[]{1,2,3,4,5};
arr[2]=new Boolean[]{true,false};
System.out.println(Arrays.deepToString(arr));
Output:
[[a, b, c], [1, 2, 3, 4, 5], [true, false]]
You are not supposed to use main for that purpose. Refactor your old class and create a new method called parse(String path). This new method should do whatever main did to make everything work.
public static void parse(String path)
By making it public other classes can access it and static means you don't need to create an instance of the class to use it. Your other class that wants to use the first class would do
MyFirstClassName.parse("file.txt");
I don't get it. Since main is your entry point I don't understand how you suppose to call it from an outside method if it is the first thing that is called when program starts. This will work only if you have two main methods declared in two different classes and you call one from the another, taking care that this last one is the one invoked by JVM at application start.
In any case I suggest you to avoid using main as a name for a generic method, it is not a keyword but I suggest you to just rename it to something else.

Categories

Resources