This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java/C# method representation in memory
I was wondering if i have an object in java, how are it's instance methods stored? Does an object have a pointer to it's instance methods?
Example:
public class MyObject {
private int x;
private int y;
[..]
}
If i plan keeping a lot (A big tree of objects for example) of these MyObjects in memory, will it make a significant difference in memory terms if apart from a getter for x and for y i define an instance method calculating the sum?
I'm trying to sort out wether i should add more instance methods or doing the calculations in another class using the getters and setters.
The instance methods of an object are stored in its class object (only one copy should exist), they are not "copied" with each new instance, instead, under the hood each instance holds a reference to the method implementation residing in the class object.
For a technical explanation, take a look at this chapter from the book "Inside the Java Virtual Machine", in particular the "Object Representation" section; it details how each instance of an object references its methods in the corresponding class. Notice that the implementation details for this are not present in the JVM specification, and they're left open to the implementors - the linked document presents several strategies.
The object needs memory for its attributes (NOTE: for object, the attribute stored is a pointer to the real object, which lies elsewhere in memory). No additional memory is needed for methods (code) as they are stored with the class.
IE:
public class MyClass1 {
private int myNumber;
}
and
public class MyClass2 {
private int myNumber;
public int MyMethod1() {
}
public int MyMethod2() {
}
public int MyMethod3() {
}
....
public int MyMethod1000() {
}
}
use the same memory per instance.
They are stored inside the class. Details are in the JVM specification.
No it will not make a significant difference. The method is actually stored in the class definition file MyObject.class. There is only one instance of that method. It gets executed for each instance but is only defined once.
Each instance is associated to a class.
The class defines the methods for all instances.
Because of this, there is no need to have pointers to methods for each instance.
An instance just store the values of the non static attributes
If you want to know the class of an instance, you just use instance.getClass().
By using getClass() you can access the list of all methods at runtime.
Related
For example if I were to create the following class:
public Class ExampleClass {
private static String field1;
private String field2;
public ExampleClass(String field2) {
this.field2 = field2;
}
public static staticMethodExample(String field1) {
this.field1 = field1;
}
}
If I were to create an instance of ExampleClass. Would that instance contain the code for the static method and/or field I created?
I have an object that will represent some data from a row in my database. I would like to create the a list of these objects from every row in the database. The database has thousands of rows. The static methods I am creating will format the values from the database before putting them into the objects constructor.
I don't want to bloat the code by having the method stored in every instance of the object. So if static methods do take up space in every instance of an object, then I would much rather create a separate class of of a name like ExampleClassBuilder. And put the formatting static methods in there.
No, static methods and fields do not take space in an instance of the class.
You are making a number of confusions here. When you compile your program, the code of each of your method (static or not) is "stored" in your compiled program (in the case of Java, in .class files). When you execute a program, static members - that "belong" to a class, like field1 in your question - are allocated once for your whole program. The other "normal" class members - like field2 in your question - are allocated for each new instance you create.
When you create a new instance of an object, the code of its various methods is not "allocated", as it already exists in compiled form in your program.
The data on the heap for an instance of this class would look roughly like*:
size (bytes) | description
--------------------------
8 | A pointer to the singleton object representing ExampleClass
8 | A pointer to the value stored in field2
That's it. The static fields aren't stored. And none of the methods are, not even instance methods! It's just the non-static fields. That pointer to the singleton? There is only one data structure representing what ExampleClass is for the entire VM. Got 1000 instances of ExampleClass? There's still only one.
Those sizes can be smaller, depends on the VM configuration.
So how would java know that an instance of ExampleClass has a method named instanceMethod? By following the pointer to the data structure describing ExampleClass itself and noticing that it has that. This:
class Foo {
public void hello() {}
}
is basically syntax sugar for:
class Foo {
public static void hello(Foo receiver) {}
}
But note that instance methods do dynamic dispatch and static methods don't. That should explain why methods (even instance methods) aren't taking up any 'memory' per instance. Only once for the entire class. The same trick cannot be applied to instance fields.
*) This is highly oversimplified and not specified by either the JLS or the JVMS, but it reflects what just about every popular VM out there actually does.
static variables and methods do not increase the size of an Object instance. These fields and methods are actually added to the Class object.
No:
When we create a static variable or method it is stored in the special area on heap: Metaspace(for Java 8 and Permgen for older versions).
Whenever a class is loaded static variables as well as methods are loaded into memory allowing any instance(which is discouraged) or direct use of them. So, any object can change the value of the variable, but they can also be manipulated without creating an instance of the class.
Check here for more https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
This question already has answers here:
Why make defensive copies in getters inside immutable classes?
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 3 years ago.
I'm learning Java and I have some doubts.
If defined a class with a private variable like
class test<A>{
private A var;
...
public A get(){
return var;
}
}
Is the get method wrong?
I think so because with this definition I can modify the variable "var" like
test<A> x = new test<A>();
A temp = x.get();
temp.set(*something*);
At the end x is changed (I tested it using Vector as A). If I understand correctly, this works because object reference (I miss C pointers, sob). Am I wrong? Maybe I don't understand the purpose of the keyword "private"! Thanks in advance!
Edit: I have no problems with "pass-by-reference" and "pass-by-value". I have doubts defining get() method for a private variable in a class (you don't say?). Please stop linking Is Java "pass-by-reference" or "pass-by-value"?
If your getter method is returning a reference to a mutable object, then this greatly weakens the quality of the encapsulation provided by your class, because it becomes possible to modify the state of an instance of your class without calling a method of the class.
One standard strategy to guard against this problem is what J. Bloch calls defensive copies (Effective Java, 3rd edition, Item 50: "Make defensive copies when needed").
This would mean creating a copy of var in the getter method, and returning that copy instead. How to do this depends on the design of A.
Because A is a type parameter, making a copy of the instance requires additional support in the design. To see how to achieve this using Java's cloning mechanism, see my answer to the post "Does it make sense to create a Copyable type interface instead of using Cloneable?".
If this is a problem, you can create a façade to protect your variable
public class Facade extends A {
A myObj;
public Facade (A obj) {
myObj =
}
public A get(){
return myObj.get();
}
public B set(Object val) {
throw new RuntimeException("Setting is not allowed");
}
}
This might be a bit too much detail for just starting, but you might review class java.util.concurrent.atomic.AtomicReference<V>, which is very similar to your example.
Generally speaking, placing instance variables in private variables, while providing access to the variable using a getter and a setter, is standard practice.
Note that your class name should be capitalized, type parameter 'V' is more standard, and the variable name would more usually be 'value'. Also, try to pick a more communicative name for the class. (Type parameter type variable could be 'ValueType', which would fit some preferences. But, single character type variable names are more usual.)
public class Wrapper<V> {
private V value;
public V get() {
return value;
}
public void set(V value) {
this.value = value;
}
}
I'd add some other point here: as others have said, you hand out the object reference and it can be modified, which could be bad.
Object orientation is about keeping the data and the code that works on it in one place. If you need getters, think what the callers of the getters need to do, and whether that action should rather be a method on the class that has the data. Your code could suffer from the Feature Envy code smell, as it violates the Tell, Don't Ask principle.
To fix this, remove the getter, and introduce new methods as needed. For example, if you have some data object that needs to get printed, you could pass the Printer to the object and have it print itself to the given Printer.
If you're dealing with a collection class (just a guess from your template parameter), you may need to keep the getter, but then you're probably not concerned with the caller changing the value anyway.
This question already has answers here:
What is the use of encapsulation when I'm able to change the property values with setter methods?
(17 answers)
Closed 5 years ago.
One of NASA's coding rules for writing safety critical programs is:
Declare data objects at the smallest possible scope
My question is, what if I have a large data object that I would like to pass around. Should I parse the object to a smaller object whenever it goes out of scope (e.g. package-level)? What if it needs to be passed to multiple packages? Do I have to create a package-level object every time?
EDIT: To clarify, I was referring to POJOs, perhaps obtained by deserializing an API response. All this time I've been making POJO classes with public fields.
Clearly, if objects of a certain class must be manipulated in different packages then either the class itself or some interface it implements must have public visibility. But that doesn't mean you need to expose every little detail about the class to public scrutiny or interference. The rule is just saying that you should not, nay, must not, expose every little detail.
Obviously some details must be publicly visible or else the class wouldn't be too useful. But there are almost always some other details which are none of the public's business, and the rule is telling you that you need to identify which details are which and not make public those details which are, in fact, none of the public's business.
The rule also relates to scope of variable declarations: declare things in the smallest scope possible. For example, if you need a variable to hold onto a result temporarily, declare a local variable inside the method where it is needed:
// YES
public class C {
private void meth1(){
int x = ...
}
}
not an instance variable in the containing class:
// NO!
public class C {
private int x; // an even worse sin would have been to make x public
private void meth1() {
x = ...
}
}
I've been given a coursework assignment where I have to build a prototype hotel booking system, in accordance with the specification, which is as follows:
You will need at least three classes:
Hotel
This should store all the essential information about a hotel,
including a name and some rooms.
Room
This should store the number of beds in a room.
Bed
This should store the size of a bed (i.e. single or double).
I'm totally confused about where to start!
I was under the impression that objects could not be contained within other objects.
For example, let's assume we instantiate a "Hotel" object. How would we then instantiate "Room" objects, and within that object, "Bed" objects?
How are these objects being stored? How do we interact with them indirectly, from another object?
Typically you don't need to nest classes into other classes, which are called inner classes, unless the work that a class takes care of can be chunked into small units that never need to be known outside it's parent class.
It sounds like the concept you want to look into is Composition. It's when an object holds a reference to another object.
public class Room {
private boolean isVacant;
public Room() {
isVacant = true; // The room starts vacant
}
// Pretend there is a way for clients to check in and out of the room
public boolean isVacant() {
return isVacant;
}
}
public class Hotel {
// Using composition, I can make an instance of one class
// available to the methods of another
private Room room101;
public Hotel(Room room101) {
this.room101 = room101;
}
public boolean isRoom101Vacant() {
return room101.isVacant();
}
}
Our hotel may not be very useful having only one room, but this example shows how you can "compose" one object into another. Methods of Hotel can now use methods of it's Room instance known as room101. You will want to think about how your rooms are structured, and how you want to represent it within your Hotel class. A few objects used to store collections of other objects include ArrayList and HashMap.
Edit:
this is a fairly difficult concept to understand before you understand what a class is compared to an instance of that class (an object). In the constructor of my sample Hotel class, I have a variable of type Room called room101. And outside of the constructor is an instance field of the same type and name.
Java will always refer to a variable or reference of the nearest scope. So if I have a method reference called room101, how can I refer to that other one declared outside the constructor, at instance level? That's where this comes in.
public class ThisExample {
// This is a separate variable at the instance level
// Lets call this global in the comments
private int a;
public ThisExample() {
// This is a separate variable in the method level,
// lets call this local in the comments
int a;
a = 5; // our local is now assigned 5
this.a = 10; // Our global is now assigned 10
this.a = a; // our global is now assigned to 5
a = this.a * 2; // our local is now assigned to 10
}
}
In short, this refers to "this" instance of a class. It's a way for an instance of a class to refer to itself as if from the outside. Just like how another object would refer to room101's method as room101.isVacant(). A method in the Room class would similarly do this.isVacant() for the same effect.
And as a final note, if there is only one declaration of a symbol within a class. The this keyword is implied. So Room can call it's own method just as well without it as long as there is no other conflicting symbols of the same name. (This doesn't occur with methods as much as with instance fields/local variables)
Hopefully this helps clear things up a bit!
Your assignment is how to model some real world concepts into code.
It appears that the core of your problem can be stated as a Guest can book a Room.
I don't want to do your work for you, so let me start by asking how you would write that in code? After that, we can address the "Hotel" and "Bed". Is this a major assignment or just a quick question? Your implementation would depend on this.
A rule to learn and apply is:
An action on an object in the real world, becomes a method of that object in an Object Oriented approach.
So I'm learning java. I'm one month in and I just learned about constructors. But I don't see the whole purpose of creating one. Why and when would I ever want to use one? I get the whole idea that it does not have a main method and you can call a constructor from your main class. Anyone can enlighten me on this topic, it would help me a great deal.
Constructors are what you use to initialize/set up the instances of your classes.
If you have an object that needs some processing before it is usable (initializing members for instance), you should do that in the constructor.
Ideally, you should never have "partially built" objects (i.e. objects that are "live", that you hold a reference to, but that are not yet usable). Without constructors, you'd be permanently creating partially built objects, and that is very error-prone. (Theory and practice don't always match, but keep that idea in mind.)
You use a constructor to create new objects. Yes, you can write Java just using static methods - but then you're really not writing object-oriented code, and you'll have a hard time using much of the standard library, either.
Most of your time you should be working with and thinking in terms of objects - and they need to be constructed before they can be used... and that's where constructors come in. They create an object, often with parameters specifying the initial state or other important information about the object.
To be honest, it's probably not worth worrying about them just yet, if you don't see the point yet. It's likely that as you learn more, you'll naturally start using objects more (maybe collections to start with, for example) and you'll get the hang of it. Rest assured, it is important to have constructors in Java, but I'm sure you'll understand why in the course of time. (Of course, if this answer has helped you to appreciate their value already, I'm glad - but if not, don't worry :)
It might seem as if you're having trouble understanding the basic concepts of objects and object-oriented programming. An explanation by example; This class represents a type of thing, namely a car:
public class Car{
// Licence plate number. This is private, so it can
// not be accessed directly from outside the class.
private String hiddenRegNr = "";
private static String description = "This is a car".
// The constructor, which sets the value of hiddenRegNr
public Car(String regNr){
hiddenRegNr = regNr;
}
// Method for reading hiddenRegNr, the only
// way to access it after instantiation.
public String getRegNr(){
return hiddenRegNr;
}
// A static method. Can be used withouth instantiation.
public static String getDesc(){
return description;
}
}
From some other class, you could call this class, and make instances of it; actual representations of different cars. They represent different cars, but are based on the same "model", i.e., the class Car.
Car myFirstCar = new Car("SR12345");
Car myOtherCar = new Car("XZ54321");
Now you have two different cars, with two different registration numbers. These are independent instances of the type car. They exist in memory, and may contain different values (in this case, different registration numbers).
myFirstCar.getRegNr(); // Will return SR12345
mySecondCar.getRegNr(); // will return xz54321
The first thing to notice here, is that you can only specify the registration number once per car, namely upon creation. That is the point of the constructor: It sets values, and does other stuff that needs to be done when objects (instances) are created.
Now, note the difference between getRegNr() and getDesc(): The keyword "Static" means that the second method is related directly to the class, and not to each instance. This means that:
Calls to getDesc() is made on the class, not an instance:
Car.getDesc();
Calls to getDesc() will return the same value for all instances of the class car
The variable description (which is also static) will be the same for all instances of Car
The static method getDesc() CAN NOT access the variable hiddenRegNr, since that variable is related to a specific instance. Trying to refer to a variable in an instance from a static context (such as getDesc()) will cause an exception to be thrown. You might say that hiddenRegNr will not have been set when you call
Car.getDesc();
because the constructor was never called, so it was never given any value.
Constructors are used to initialize a class and give parameters to a class. What is important is that they let you set the class state on creation. This allows you to use specific instances of a class with different data field values instead of relying on purely static information. Take the following example:
class Obj {
private int state = 0;
public Obj(int state) {
this.state = state;
}
public Obj() {
state = 1;
}
}
Now in main (or wherever) you can have:
Obj obj1 = new Obj();
Obj obj2 = new Obj(2);
The two objects have different states (one is at state 1, the other is at state 2). If you were relying on static methods and members, the objects would share one state and would not be independent of each other.
It is also important to note that constructors (specifically the new keyword) allocate memory for a given object internally so you don't have to worry about using malloc and other memory management. So they are important in that sense as well.
It is used to create objects. Objects are the main concept in OOP, so creating them is an important step. The main class method is just an entry point to your program. If you don't create objects your program will be procedural rather than object-oriented. This is why to use a constructor.
And why to create a constructor - sometimes you need to construct an object with some required parameters. There is also a default no-argument constructor, but if you want to initialize your object with additional arguments - you create a constructor taking those arguments.
Actually constructor is needed IF you need to assign unique initial state to an instance of a class. In Java i only just realized (by a friend) that we can do this:
public class MyClass1 {
private class MyClass2 {}
private MyClass2 myobj2 = new MyClass2();
}
So no need for implicit constructor.
But if something like follows, you need constructor.
public class MyClass1 {
private class MyClass2 {
private int id_ = 0;
public MyClass2(int id) { id_ = id; } // how to reach this?
}
private MyClass2 myobj2 = new MyClass2(1); // (this doesn't work. Not unique)
public MyClass1(int id) { myobj2 = new MyClass2(id); } // by this!
}
MyClass1 obj1 = new MyClass1(100);
MyClass1 obj2 = new MyClass1(200);
I will give you an example, imagine you have a car class.. when you call the constructor of the car class you have an car object. on this car object is possible to use diffent methods. And you could create as many as car objects as you want.