Classes are a software bundle of variables and functions, also known as a blueprint that defines the variables and methods common to objects of a certain kind. So why are objects also known as instances of a class?
Like you said, class is a blueprint; objects are made using those blueprints.
Its like you have a blueprint of a car - you have one blueprint, but many cars based on that blueprint.
According to dictionary.com: An instance is - "an example or single occurrence of something"
An object is a single occurrence or realization of a class.
Class is a syntactic notion, governed by compile time rules, such as naming, scope, etc. That your program defines a class A means that 1) you have a type, and 2) that the right class loader will be able to find A's bytecode on the classpath. But it doesn't mean that your running program is able to operate on this class. An operable object with its own state must be first instantiated with new, which, at run time, will cause the classloader to allocate memory required to hold that state. You can have any number of objects of a single class A, all of type A but with their own state memory.
Related
As per the definition in Java. If class doesn't occupy memory and just acts like a template, then why are we creating objects(main method) inside curly braces of class. Doesn't that mean now class also occupies memory because of objects present inside of it?
Trying to understand the definition of a class
There are three concepts to keep separate here: the class, the instance, and the stack.
class SomeClass {
static int staticValue = 0;
/* non-static */ int instanceValue = 0;
int someMethod() {
int stackValue = 42;
SomeClass instance = new SomeClass();
// ...
}
}
The class acts as a template, yes. In some languages other than Java, the class takes up no memory of its own: it merely describes the memory layout of the class's instances. For a beginner definition of OOP concepts you can think of that as true.
In Java this is not quite true for three reasons:
There is an object instance for SomeClass, accessible via SomeClass.class, which does take up memory. This instance allows you to look up information about the class itself, which is sometimes called "reflection".
The static field staticValue is shared among all instances of SomeClass, so in a sense the class takes up a small amount of memory to contain this shared value.
SomeClass contains methods like someMethod, and that code has to be in memory in order to run. If you're willing to consider code as requiring memory, and that the code is associated with the class, then the class consumes memory. People talking about OOP concepts aren't usually talking about the memory consumed by the code itself, though.
This can be compared to instances of the class SomeClass, which at a minimum contain a separate value of instanceValue for every instance you create. Instances don't have their own code, and do (in Java) contain a reference to their Class instance accessible via getClass().
Finally, the method someMethod and your main example do use references and local variables that consume memory, but in a different place than the instances or classes. This place is called a "stack", in part because as you call methods and those call further methods, the stack grows like a stack of papers on a desk. This means that there may be many copies of stackValue existing at once, one for each time you have called someMethod that hasn't finished yet. Each value of stackValue is discarded whenever its corresponding invocation of someMethod returns. These aren't directly tied to classes or instances, other than that they are code that might be considered associated with a class as in #3 above. Disregarding the memory consumed by the compiled code itself, the instance does not contribute to SomeClass or its instances consuming any more memory in ways that matter to OOP.
(Instances created with new are not a part of a "stack" but rather are part of the "heap", at this level of explanation, and that includes the SomeClass.class instance and any instances of SomeClass. Some languages require careful management of the heap's memory, but Java manages it for you through a process called garbage collection. Primitives like stackValue and the reference named instance are kept on the stack, though.)
In a java program, when a class is loaded into the method area the Class type object is created in the heap area. Questions:
If 10 .class files are loaded then 10 Class type objects are created right?
What is the purpose of creating the Class type object for every .class file by JVM?
There are probably many many reasons. Like: you want to write code such as:
Class<Foo> fooClass = Foo.class;
Annotation[] annotations = fooClass.getAnnotations();
Meaning: the class Class enables you to programmatically inspect (reflect) on your types. Or to use reflection to invoke constructors or methods based on raw strings.
And of course: the JVM itself needs all kinds of information about the classes it knows. So it makes perfect sense to "collect" all that information right at the point when the class is loaded.
Imagine you are a shop owner, and you decide to carry a new item. One of the things to do: update your internal inventory that lists all items, and maybe describes the attributes/properties that matter to you.
After loading a .class file, JVM will create an object of the type java.lang.Class in the Heap area. We can use this class object to get Class level information. It is widely used in Reflection.
Source : https://www.geeksforgeeks.org/object-class-in-java/
I believe this part is handled by JVM's ClassLoader system.
Except the first class of main(), ClassLoader system creates class type objects statically if new is triggered or dynamically if Class.forName() is used. In Object oriented concept class type object is reference to the class.
Consider the following code snippet:
class Parent {
Parent() {
this = new Child();
}
}
class Child extends Parent { }
The above would throw a syntax error: The left hand side of an assignment operator must be a variable
In java, the this keyword stores the memory address of the current calling object. I wish to overwrite the current object with an instance of the class' subclass. I understand the above snippet is throwing an error as this is not a variable and is probably immutable.
However, I wish to know why java doesn't allow this above feature? Is there any downside to it?
EDIT: This question occurred to me with reference to a Natural Language Processing (NLP) context. For example, in the French language, every verb has to end with 'er', 'ir' or 're'. All verbs have certain features in common. However, every verb must be either one of the three types mentioned above. So in the constructor of the parent class 'Verb', I want to categorize the object created as an 'ErVerb', 'IrVerb' or 'ReVerb'.
There are two scenarios:
If you let this be instantiated to any Object whatsoever, not necessarily one in the type hierarchy, then an instantiation would have no guarantee about the contents of its reference. This breaks a couple things, most notably the entire concept of object-oriented programming.
If you restrict this to be instantiated to any subclass of the parent class, then that subclass constructor would call the parent constructor infinitely many times, causing a StackOverflowError.
It doesn't make any sense to construct a subclass instance inside the parent's constructor and substitute the actual parent instance with the created child instance.
Despite the nasty StackOverflowError pointed out in the comments and in the other answer, there's no use case for doing this. In general, it's absurd (from the logical point of view) to create a child while creating the parent.
Consider the following reasoning:
A specific car is being assembled in a factory. The process to assemble a specific car consists of many steps.
Some of these steps only occur when assembling the specific car, while others occur both when assembling the specific car and when assembling other vehicles, such as a specific van.
Now let's suppose that one of these general steps that occur when assembling many vehicles (including both the specific car and the specific van), indicates that we must assemble a new specific van and let it be the general vehicle being assembled.
Now, the specific car we were assembling would have become this new specific van. But it's impossible for a car to be a van => ABSURD.
We do have a cache (Map) with objects of Class TestClass. Another classloader initializes/loads TestClass at runtime again, so below code will threw a ClassCastException:
TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException
ClassCastException when casting to the same class
Alright, I do understand this issue up to this point.
So, I was trying to find background information why is TestClass.class not equals TestClass.class. I assume that the different classloader set a different id to the ReferenceType? Anyone able to explain the background to me?
Best page I've found:
http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm
Yes, your research points to the right direction: the same class definition loaded by different class loaders is seen as two distinct classes by the JVM. Thus casting between them fails with ClassCastException.
I think the difference is simply because there are two distinct class token objects in play. It has to be like this, since the classes loaded by the different loaders may in fact be different versions of the same class. It is known that the class token for every class is unique (within the same classloader realm, that is). It would open up a can of worms if the JVM started to compare class tokens by their various attributes, rather than by physical equality (==).
What you experienced is the reason why custom class loaders exist. They allow to load different class with the same name in one JVM. The identity of a class in a JVM is given by the tuple consisting of the class name and the class loader. In the language Java a class is identified just by fully qualified name.
Anyone able to explain the background to me?
As Péter Török already explained they are considered different when loaded from different classloaders.
The background is that an application server should be able to support different versions of an application e.g. different versions of the same libraries included in your ear-files.
There is no mystery. Runtime equality of types is defined in the Java Language Specification as follows:
"At run time, several reference types with the same binary name may be loaded simultaneously by different class loaders. These types may or may not represent the same type declaration. Even if two such types do represent the same type declaration, they are considered distinct."
JLS 4.3.4 - When reference types are the same. (2nd paragraph)
I have a large tree-like data structure of objects which behave mostly identical but differ in one or two methods that calculate some keys used to navigate through the structure. The divergent behaviour depends on where the objects are in the structure.
I was starting out with an abstract base class and have several subclasses that implement each type of behaviour. This gives me around ten subtypes which are a) hard to name intelligently and b) look a little unwieldy in my project's source folder, both because they are so similar.
I would prefer having a single factory class that doles out instances of anonymous subclasses on the fly. This would give me a lot of flexibility and open the door for a lot of nice improvements, such as sharing data and parametrizing stuff and would look a lot cleaner in my code structure. However, the whole thing is very sensitive to memory footprint and memory access time, and I'd have lots of these objects. Do I have to consider any disadvantages or pecularities of anonymous classes?
Like non-static inner classes, anonymous classes have a hidden reference to the class they're defined in, which can cause problems if you use serialization and of course prevent objects of the outer class from being eligible for GC - but that's unlikely to be a problem if you do it in a single factory class.
Anonymous classes are not different than named classes.
But yes, having many objects can impact your memory footprint, and performance (garbage-collection).
From what you tell, I wonder if it would be possible to split your class in two parts:
All the constant methods in one class (no subclass of this class).
All variable methods (see later) are encapsulated in a Position interface. You can have a few classes that implement it. The objects of these classes would have no state, so they can be shared instances which is excellent for performance and memory).
Variable methods : calculate some keys depending on the position in the structure.
As mentioned an anonymous inner class usually has a hidden reference to the class in which it is declared. However, you can eliminate this by declaring the anonymous class from inside a static method (simple, and not perfectly obvious).
The major disadvantage to this technique is that the classnames seen in jars will be numbered (like "MyClass$0.class") and not easily identifiable in stacktraces (except of course by using the line numbers) and without toString() methods not easily identifiable in your own println statements.
Declaring static inner classes is a great technique. It will eliminate all these disadvantages and keep your file hierarchy compact. Also consider making these inner classes private or final unless you need to extend them.
A class is a class. It doesn't matter whether it's a "top-level" classes, a regular inner class, a local inner class, or an anonymous inner class.
Non-static inner classes, or inner classes that access private members of their enclosing class will have a tiny bit of extra code in them. To non-static inner classes, the compiler adds a member variable that references the enclosing instance. If an inner class accesses any private members of the enclosing class, the compiler will synthesize an accessor in the enclosing class with "package-private" (default) accessibility.