Skip to main content

Why Java is Purely Object Oriented Language Or Why Not

Some years back when I have started learning Java I get to know that Java follows Object Oriented Programming paradigm and everything in Java is an object either it is a String (which was a char array in C) or an array itself.
But later on I found on Internet people saying that Java is actually not purely Object Oriented because everything in Java is not an object, for example:
  1. All primitive types (char, boolean, byte, short, int, long, float, double) are not objects because we are not able to do any object like operation (using . and calling methods) on them.
  2. I have also found some people some saying that all static content (variables and methods) does not belong to any object so they are non object things.
Due to my little bit knowledge and less experience I easily accepted these reasons and started to believe that Java is not a purely Object Oriented Programming Language.
But later on I found that for every object JVM creates two objects
  1. The object itself.
  2. And one Class level object (referred by ClassName.class syntax) which got created only once while Classloader loads the class into memory. And all static content of that class belongs this Class object and all other objects of that class refer to this class level object for all static content.
For Example for below statement, there will be two objects
Employee emp =  new Employee();
One is emp itself and another one is the class level object of employee class which we can refer by Employee.class. And this class level object holds all the static content of Employee class either it is a variable or method. If we are accessing any static content through the emp object it points to Employee.class object to access that.
That is the reason why a static variable got changed for every object even if we change it for a single emp object because all emp objects are pointing same copy of that variable from Employee.class object.
Now 2nd point got canceled because the static content does belong to an object. But the 1st point is still there and we still have primitive data types which are not object in Java.
As mentioned earlier primitive types are not object because we can’t perform any object related functionality one those. To overcome this problem Java introduced Wrapper classes for every primitive type e.g. Integer for int, Long for long, Character for char. Now we can create objects for primitive types and perform all object related operations on them.
And due to autoboxing (automatic unboxing-boxing, boxing-unboxing), we can directly assign a primitive literal to its Wrapper class reference. But still, we can’t perform these operations on primitives variables we always need to create objects of the respective Wrapper class.
For Example
Integer obj = new Integer(5); // here we can do obj.toString();
int i = 5; // but we can't do i.toString(); here
As far as it is clear that we primitive types are not objects but that’s actually an end user perspective (Java developers are end user to Java because we are using it not creating it).
JVM internally treats all primitive types as objects and proof of this can be found in source code or Javadoc of class Class, according to source code class Class
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects

And Javadoc code of Class.isPrimitive() method
public boolean isPrimitive()
Determines if the specified Class object represents a primitive type.
There are nine predefined Class objects to represent the eight primitive types and void. These are created by the Java Virtual Machine, and have the same names as the primitive types that they represent, namely boolean,byte, char, short, int, long, float, and double.
These objects may only be accessed via the following public static final variables, and are the only Class objects for which this method returns true.
Returns:
true if and only if this class represents a primitive type
Since:
JDK1.1
See Also:
Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE
If you will open Javadoc of class Class and do a ctrl + F for “primitive” word you will find lots of reason to believe that JVM treats all primitive types as objects internally.
And let’s open Integer.TYPE entry from above See also section you will found
public static final Class<Integer> TYPE
The Class instance representing the primitive type int.
And if you will write below line in your program using eclipse
Integer.TYPE i = 5;
You will get a compilation error saying Integer.TYPE cannot be resolved to a type with a hint from eclipse to change it to int.


Why should we use primitive types


primitive-type-and-wrapper-classes-in-java




 



So if JVM creates objects for all primitive types why do we need to use primitive types instead of creating an object of its respective Wrapper classes. That’s because JVM creates these native objects for primitive types internally and those objects are very lightweight and optimized than their respective wrapper class objects and due to this, they have less functionality e.g. we can’t call methods on them because they don’t have any.
We should use primitive types:
  1. Because they are fast e.g. below program takes 9 seconds to run on my machine while it takes 0 seconds if I convert Long sum to long sum if that's any indication why we use primitives.
public static void main(String[] args) {
long millis = System.currentTimeMillis();
  Long sum = 0L; // uses Long, not long
  for (long i = 0; i <= Integer.MAX_VALUE; i++) {
  sum += i;
  }
System.out.println(sum);
System.out.println((System.currentTimeMillis() - millis) / 1000);
}
  1. They allow us to use native equality operator ==


new Integer(3) == new Integer(3); // false
new Integer(100) == new Integer(100); // false
Integer.valueOf(5) == Integer.valueOf(5); //true
Integer.valueOf(100) == Integer.valueOf(100); //false
4th statement give false because the 256 integers closest to zero [-128; 127] are cached by the JVM, so they return the same object for those. Beyond that range, though, they aren't cached, so a new object is created.


So we can say JVM treats all primitive types as objects internally, however, we can’t them in that way and we have got Wrapper classes for that.
This is why Java is purely Object Oriented Language, Please mention in comments what do you think Java is a purely Object Oriented Language or not.

Comments

  1. Integer obj = new Integer(5); // here we can do i.toString();
    may be, this need to be
    Integer obj = new Integer(5); // here we can do obj.toString();

    ReplyDelete
    Replies
    1. Thanks for mentioning it @Andrey, I have corrected it.

      Delete
  2. and
    Integer.valueOf(100) == Integer.valueOf(100); //will be true
    but
    Integer.valueOf(200) == Integer.valueOf(200); //false

    ReplyDelete
  3. public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
    return IntegerCache.cache[i + 128];
    else
    return new Integer(i);
    }

    ReplyDelete
  4. It's very interesting and useful for students
    Java Online Training

    ReplyDelete

Post a Comment

Popular posts from this blog

Why an outer Java class can’t be static

In a previous blog , I talked about why we can not define an outer class using private or protected keywords. If you have not read it, please go ahead and give it a look. I this article I will talk what is the use of the static keyword, why an outer Java class can’t be static, why it is not allowed in Java to define a static outer class. In order to understand that first, we need to understand what is the static keyword used for, what purpose it solves and how does it works. What does static keyword do Every Java programmer knows that if we need to define some behavior (method) or state (field) which will be common to all objects we define it as static. Because static content (behavior or state) does not belong to any particular instance or object, it will common to all objects and all objects are free to change any static field and every change will be visible to every object. We do not need to create any object of the class to access a static field or method, we can directly...

Why Single Java Source File Can Not Have More Than One public class

According to Java standards and common practices we should declare every class in its own source file. And even if we declare multiple classes in the single source file (.java) still each class will have its own class file after compilation. But the fact is that we can declare more than one class in a single source file with below constraints, Each source file should contain only one public class and the name of that public class should be similar to the name of the source file. If you are declaring the main method in your source file then main should lie in that public class If there is no public class in the source file then main method can lie in any class and we can give any name to the source file. If you are not following 1st constraint then you will receive a compilation error saying “ The public type A must be defined in its own file ”.  While if you are not following the second constraint you will receive an error “ Error: Could not find or load main class User ” after ...

How Does JVM Handle Method Overloading and Overriding Internally

In my previous article Everything About Method Overloading Vs Method Overriding , I have discussed method overloading and overriding, their rules and differences. In this article, we will see How Does JVM Handle Method Overloading And Overriding Internally, how JVM identifies which method should get called. Let’s take the example of parent class  Mammal and a child  Human classes from our previous blog to understand it more clearly. public class OverridingInternalExample { private static class Mammal { public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); } } private static class Human extends Mammal { @Override public void speak() { System.out.println("Hello"); } // Valid overload of speak public void speak(String language) { if (language.equals("Hindi")) System.out.println("Namaste"); else System.out.println("Hello"); } @...