I do consider myself quite experienced in Java but there are still some minor basic things that I'm not really sure of.
I always try to write maintainable, easy readable code and aim for highest efficency.
For example I only call a "new"-Operator only when it is really needed.
That is because I don't want to allocate memory unnecessarily.
But what about supporting Variables?
Lots of people tend to declare a String just to assign some long ass method call like this:
String helper = Class.method1().method2(param).getter();
I always wonder if that doesn't allocate more memory than needed.
The getter returns a new Object already and now even more memory is allocated by referencing it in addition.
When I have use this getter more than once a helper string is convenient, but if it is needed only once wouldn't it be better to pass that method directly instead of declaring a new variable?
Does this actually allocate memory to the heap?
Object a, b, c, d, e ,f , g, h, i, j ...;
I hope some more experienced Java guys than me can tell me how they handle basic stuff like this. thanks! :)
Does this actually allocate memory to the heap?
No, it is allocated on the stack. Global variables are allocated on the heap.
When your method finishes it will return the allocated memoryspace it took from the stack, and the variable will no longer be of any concern.
I always wonder if that doesn't allocate more memory than needed
It will allocate memory on the stack for a reference to the variable. This reference is not needed if you pass the function as an argument. However, the function still has to be evaluated and it's returned value will be placed on the stack. If you declare a variable for it, a few extra writes and reads has to be performed, which should in most cases not be of any concern with respect to todays efficient computers.
If the member can only be set via an accessor (a "setter" method), I prefer the first style. It provides a hint that the initialized value is the default upon construction.
If the member can be specified during construction, I generally pass the default value to an appropriate constructor from constructor with fewer parameters. For example,
final class Example {
private final String name;
Example() {
this("My Example");
}
Example(String name) {
this.name = name;
}
}
Related
i don't know if its asked before (i searched but couldn't find)
Is there any difference between the following 2 code blocks?
1:
// Let's say we want to get variable from non-static object
Object a = new Object();
int varWeWant = a.getVariable();
2:
int varWeWant = new Object().getVariable();
as you see second option is one-line code
and i know the java, both codes create object first and retrieve variable via method but i'm not java expert so i wonder if they have any differences ?
Sorry if it is silly question :D
i was just wondered this for too long
thanx
The first creates an object that can be referred to later, then calls a method on it.
The second creates a temporary object that can only be used to call that single method.
Really, if you're using the second way, you should question if the object was necessary in the first place. It might make more sense to just make that method a standalone function unless you're using the Builder or similar pattern.
both produce the same BUT option 2 is the object instance an anonymous reference... that means you can not do anything with that object after that statement...
int x = new Object().getVariable();
This is done when the object have one time use.
Object a = new Object(); //Creates an object named a
This is done when object has multiple variables and functions. This way object is created only once and the variables and functions are called. If we were to use new Object().getSomeFunction() every time then new object is created every time. Its expensive memory wise and more lines has to be written.
The result in varWeWant is the same.
Some minor differences:
In the first version you can later use the Object for other purposes, as you stored a reference to it in the a variable (that's obvious).
Introducing the variable a comsumes a small amount of memory.
As long as the variable a refers to this Object, the garbage collector cannot reclaim its memory. (But compiler and runtime optimizations might be able to free the memory earlier, as soon as a is no longer used).
Storing the reference in a variable will take a tiny amount of time.
I have always thought that I have to initialize a class, before I can call it's non-static method, however, I came across a solution which had a method like this in it:
public String someStringMethod(){
return new MyClass().toString();
}
So I may be new in development, but is it a good practice? Is this a better way to call a method than the "classic" (see below) way?
public String classicStringMethod(){
MyClass cl = new MyClass();
return cl.toString();
}
Do they have any performance difference? Does the first way has a "special name"?
No significant difference
As the comments explained, both approaches are semantically the same; both ways achieve the exact same result and the choice is really just a stylistic difference.
The second approach assigns the new object to a reference variable. The first approach skips the use of a reference variable. But in both cases the class was used as a definition for instantiating an object, and then the toString method was called on that object.
Semantically, first (chained/fluent) syntax usually informs you that the created object will be used only for a single chain of operations, and discarded afterwards. Since there's no explicit reference exported, it also signals that the scope of life of the object is limited to that very statement. The second (explicit) one hints that the object is/was/will be used for additional operations, be it another method calls, setting a field to it, returning it, or even just debugging. Still, the general notion of using (or not) temporary helper variables is just a stylistic one.
Keep in mind that the variable is not the object. For example, the line Dog hershey = new Dog( "Australian Shepard" , "red", "Hershey" ); uses two chunks of memory. In one chunk is the new object, holding the state data for the breed and color and name. In the other separate chunk is the reference variable hershey holding a pointer to the memory location of the memory chunk of the Dog object. The reference variable lets us later refer to the object.
Java syntax makes this jump from reference variable to object so seamlessly that we usually think of hershey as the Dog object “Hershey”, but in fact they are separate and distinct.
As for performance, any difference would be insignificant. Indeed, the compiler or JVM may well collapse the second approach’s two lines into the first approach‘s single line. I don't know for sure, and I don't really care. Neither should you. Our job is to write clear readable code. The job of the compiler and JVM is to run that code reliably, efficiently, and fast. Attempting micro-optimizations has been shown many times to be futile (or even counter-productive) as the JVM implementations are extremely sophisticated pieces of software engineering, highly-tuned for making such optimizations. You can best assist the compilers and JVMs by writing simple straight-forward code without “cleverness”.
Note that the second approach can make debugging easier, because your debugger can inspect the instantiated object by accessing the object via the reference variable, and because you can set a line breakpoint on that particular constructor call explicitly.
I have a rather simple question with an inkling as to what the answer is.
My generalized question:
What is actually going on when you declare a member variable, be it public or private, and for all permutations of variable types, e.g. static vs const vs regular variables?
class some_class
{
private:
static const std::string str;
public:
...
}
I have kind of realized that in C++ there is no notion of a non-variable, that is, a non-constructed variable as I was kind of taught to believe exists with languages like Java. The same may also be true in Java, however it is not the way I was taught to think of things so I'm trying to come up with the correct way to think of these non-initialized variables.
public class main {
public static void main(String[] args) {
String str; // A kind of non-variable, or non-constructed variable (refers to null).
str = new String(); // Now this variable actually refers to an object rather than null, it is a constructed variable.
}
}
Since C++ allows you to initialize member variables in the constructor through initializer lists, and I have proven to myself via use of a debugger that the variable doesn't exist before it is initialized through the initializer list (either explicitly or by default), what is, then, actually going on behind the scenes when you declare the member variable?
Tricky question -- it's ambiguous depending on perspective.
From a pseudo-machine perspective, normally adding a non-static plain old data type to a class makes that class type bigger. The compiler also figures out how to align it and relative memory offsets to address it relative to the object in the resulting machine code.
This is pseudo-machine level because at the machine level, data types don't actually exist: just raw bits and bytes, registers, instructions, things like that.
When you add a non-primitive user-defined type, this recurses and the compiler generates the instructions to access the members of the member and so on.
From a higher level, adding members to a class makes the member accessible from instances (objects) of the class. The constructor initializes those members, and the destructor destroys them (recursively triggering destructors of members that have non-trivial destructors, and likewise for constructors in the construction phase).
Yet your example is a static member. For static members, they get stored in a data segment at the machine level and the compiler generates the code to access those static members from the data segment.
Some of this might be a bit confusing. C++ shares its legacy with C which is a hardware-level language, and its static compilation and linking affects its design. So while it can go pretty high-level, a lot of its constructs are still tied to how the hardware, compiler, and linker does things, whereas in Java, the language can make some more sensible choices in favor of programmer convenience without a language design that somewhat reflects all of these things.
Yes and no.
A variable of class type in Java is really a pointer. Unlike C and C++ pointers, it doesn't support pointer arithmetic (but that's not essential to being a pointer--for example, pointers in Pascal didn't support arithmetic either).
So, when you define a variable of class type in Java: String str;, it's pretty much equivalent to defining a pointer in C++: String *str;. You can then assign a new (or existing) String object to that, as you've shown.
Now, it's certainly possible to achieve roughly the same effect in C++ by explicitly using a pointer (or reference). There are differences though. If you use a pointer, you have to explicitly dereference that pointer to get the object to which it refers. If you use a reference, you must initialize the reference--and once you do so, that reference can never refer to any object other than the one with which it was initialized.
There are also some special rules for const variables in C++. In many cases, where you're just defining a symbolic name for a value:
static const int size = 1234;
...and you never use that variable in a way that requires it to have an address (e.g., taking its address), it usually won't be assigned an address at all. In other words, the compiler will know the value you've associated with that name, but when compilation is finished, the compiler will have substituted the value anywhere you've used that name, so the variable (as such) basically disappears (though if you have the compiler generate debugging information, it'll usually retain enough to know and display its name/type correctly).
C++ does have one other case where a variable is a little like a Java "zombie" object that's been declared but not initialized. If you move from an object: object x = std::move(y);, after the move is complete the source of the move (y in this case) can be in a rather strange state where it exists, but about all you can really do with it is assign a new value to it. Just for example, in the case of a string, it might be an empty string--but it also could retain exactly the value it had before the move, or it could contain some other value (e.g., the value that the destination string held before the move).
Even that, however, is a little bit different--even though you don't know its state, it's still an object that should maintain the invariants of its class--for example, if you move from a string, and then ask for the string's length, that length should match up with what the string actually contains--if (for example) you print it out, you don't know what string will print out, but you should not get an equivalent of a NullPointerException--if it's an empty string, it just won't print anything out. If it's a non-empty string, the length of the data that's printed out should match up with what its .size() indicates, and so on.
The other obviously similar C++ type would be a pointer. An uninitialized pointer does not point to an object. The pointer itself exists though--it just doesn't refer to anything. Attempting to dereference it could give some sort of error message telling you that you've attempted to use a null pointer--but unless it has static storage duration, or you've explicitly initialized it, there's no guarantee that it'll be a null pointer either--attempting to dereference it could give a garbage value, throw an exception, or almost anything else (i.e., it's undefined behavior).
I am still a beginner to java and I have a question on an efficient way to pass in parameters. When passing in objects in a method is it more efficient to pass in portions of an object or does it not matter at all? for example, lets say I have a Person object which has several attributes (name, height, gender, location, hairColor etc.) and I have a method which needs to work on two of these attributes. When I pass the info into the method, does it save me memory, process time etc to only pass in the needed info (like name and location) or is it the same as just passing in the whole person object?
is:
public void getNamePlace(String name, String location){
\\\\work here
}
any different efficiency-wise than:
public void getNamePlace(Person person){
\\\\work here and get the name location in the method
}
Thanks a lot for the help. I'm sorry if it is a dumb question but I'm trying to figure out the best mentality to approach this. Thank you.
p.s. I am thinking more on the method call itself. How does it work. In isolation, is:
public void getNamePlace(String name, String Location) --> More bits passed around and memory used than --> public void getNamePlace(Person person)
You're passing reference values. The more values you pass, the more work is being done.
Is it a measurable difference? Technically, yes–but miniscule in the extreme (e.g., another parameter is another bytecode, and that's all. Vanishingly small difference in performance and class size.)
Is it an appreciable difference? No.
The mentality here is that premature optimization, particularly at this level, isn't something to deal with.
Others have pointed out there are readability and data issues that are more important.
It "doesn't matter at all". In Java you only pass the reference of the object (as a value) to the function. It's a very small data type and it tells the VM where the object is located in memory.
Take a look at Is Java "pass-by-reference" or "pass-by-value"? for a very good answer ;)
When you use this:
public void getNamePlace(Person person){
\\\\work here and get the name location in the method
}
nothing actually gets passed to the method except a reference (a "pointer" in a loose sense) to the actual object of type Person. No copying of members takes place, as you are instead instructing the method "you can find all you need at this memory location".
So technically passing a limited number of fields from person is actually worse than passing "the entire person" (although the difference is not noticeable anyway). :)
Objects in java are passed by reference. The short answer is to just pass your objects.
The long answer is that object references are either 32 or 64 bits, depending on your java installation. A 64 bit quantity is twice as large as the JVM's typical padding size (which is often 32 bits even on 64 bit systems under some circumstances). There is a small amount of overhead associated with dereferencing the reference, but the JIT compiler will usually optimize it to a constant amount rather than a repeated hit. Furthermore, you will always have to dereference it sometime, either inside the function or outside. You might as well just save on the stack space and pass the object by reference.
It doesn't matter at all considering time and efficiency.
But it does matter if you want to write readable code. - It's always nice to group logically connected items, as object that they represent
for example:
writeLetterTo(person);
is much better than that:
writeLetterTo(name, surname, address, city, country);
if only all those parameters can be taken somehow from person object.
Another example:
addTwoPionts(x1, x2, y1, y2); // ugly
addTwoPoints(point1, point2); // far better
Apart from the method parameters, there are a couple of things you should tweak:
public void getNamePlace(Person person){
\\\\work here and get the name location in the method
}
to get the habits right
getNamePlace method name when it returns nothing is not convention compliant. getXXXX should return the value.
Since getNamePlace will operate on Person so it should be defined in the class itself and then you need not to pass any parameters.
Finally to answer your question, you shouldn't bother too much about such micro-optimization so initially in language learning graph... It hardly makes any difference.
You're passing around an extra address using getNamePlace(String,String) instead of getNamePlace(Person).
Java will not make a copy of the Person object when passing it; it passes the reference.
Similarly, Java will not make a copy of the Strings when passing them; it passes the references.
Will you notice a significant performance difference? No.
I personally wouldn't be too concerned with this. If you are really concerned with performance that much you probably should look at using a lower level language. As others have said, there isn't really any performance difference between the two especially when it comes to just passing variables.
If you are truly having performance issues I would suspect there are many other places in your code that are slowing you down instead of parameter passing.
What happens in the memory when a class instantiates the following object?
public class SomeObject{
private String strSomeProperty;
public SomeObject(String strSomeProperty){
this.strSomeProperty = strSomeProperty;
}
public void setSomeProperty(String strSomeProperty){
this.strSomeProperty = strSomeProperty;
}
public String getSomeProperty(){
return this.strSomeProperty;
}
}
In class SomeClass1:
SomeObject so1 = new SomeObject("some property value");
In class SomeClass2:
SomeObject so2 = new SomeObject("another property value");
How is memory allocated to the newly instantiated object and its properties?
Let's step through it:
SomeObject so1 = new SomeObject("some property value");
... is actually more complicated than it looks, because you're creating a new String. It might be easier to think of as:
String tmp = new String("some property value");
SomeObject so1 = new SomeObject(tmp);
// Not that you would normally write it in this way.
(To be absolutely accurate - these are not really equivalent. In the original the 'new String' is created at compile time and is part of the .class image. You can think of this as a performance hack.)
So, first the JVM allocates space for the String. You typically don't know or care about the internals of the String implementation, so just take it on trust that a chunk of memory is being used to represent "some property value". Also, you have some memory temporarily allocated containing a reference to the String. In the second form, it's explicitly called tmp; in your original form Java handles it without naming it.
Next the JVM allocates space for a new SomeObject. That's a bit of space for Java's internal bookkeeping, and space for each of the object's fields. In this case, there's just one field, strSomeProperty.
Bear in mind that strSomeProperty is just a reference to a String. For now, it'll be initialised to null.
Next, the constructor is executed.
this.strSomeProperty = strSomeProperty;
All this does is copy the reference to the String, into your strSomeProperty field.
Finally, space is allocated for the object reference so1. This is set with a reference to the SomeObject.
so2 works in exactly the same way.
Determining Memory Usage in Java by Dr. Heinz M. Kabutz gives a precise answer, plus a program to calculate the memory usage. The relevant part:
The class takes up at least 8 bytes. So, if you say new Object(); you will allocate 8 bytes on the heap.
Each data member takes up 4 bytes, except for long and double which take up 8 bytes. Even if the data member is a byte, it will still take up 4 bytes! In addition, the amount of memory used is increased in 8 byte blocks. So, if you have a class that contains one byte it will take up 8 bytes for the class and 8 bytes for the data, totalling 16 bytes (groan!).
Arrays are a bit more clever. Primitives get packed in arrays, so if you have an array of bytes they will each take up one byte (wow!). The memory usage of course still goes up in 8 byte blocks.
As people have pointed out in the comments, Strings are a special case, because they can be interned. You can reason about the space they take up in the same way, but keep in mind that what looks like multiple copies of the same String may actually point to the same reference.
Points to remember:
When a method is called, a frame is created on the top of stack.
Once a method has completed execution, flow of control returns to the calling method and its corresponding stack frame is flushed.
Local variables are created in the stack.
Instance variables are created in the heap & are part of the object they belong to.
Reference variables are created in the stack.
Ref: http://www.javatutorialhub.com/java-stack-heap.html