CSC/ECE 517 Fall 2012/ch1 1w21 aa: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
 
(38 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<p>''' Primitive Objects '''</p>
'''Primitive objects in object-oriented languages''' - based on the [http://expertiza.csc.ncsu.edu/wiki/index.php/CSC/ECE_517_Fall_2011/ch3_3h_ss wiki page] from previous year


== Introduction ==
== Introduction ==  
Primitive datatypes are those that are not defined in terms of other data types[http://ece.uprm.edu/~ahchinaei/courses/2010jan/icom4036/slides/11icom4036DataTypes1.pdf]. It is a basic or in-built type that a programming language provides for its users. These data types can be used for building other complex and composite data types [http://en.wikipedia.org/wiki/Primitive_data_type]. In most languages, primitive types usually consist of basic value types for representing the data to be stored. As these data types are built-in, the compilers for these languages usually provide inbuilt support for these data types and so would support most basic operations. In dynamically typed languages like Ruby, these are represented as objects and are referred to as primitive objects. This article discusses the various primitive data types/objects that are present in various objected oriented programming languages and their benefits.


Some of the common data types that are present in most programming languages are
In any programming language, the [http://en.wikipedia.org/wiki/Data_type data type] refers to the class of data which contains specific type or range of values. Data types are used along with variables used in the program. The data type tells us what kind of values the variable can store, what is the range of the values and how much space the values take in memory etc.
*'''Integer''' - used to hold whole numbers. Can be signed or unsigned and include various types like <code>byte</code>, <code>short</code>, <code>int</code>, <code>long</code>, etc.
*'''Character''' - used to hold single character, digit or symbol or a sequence of any combination of them that is stored in numeric coding. Usually stored in ASCII encoding. '
*'''Floating-point''' - used to represent real numbers with limited precision. They usually comprise of an exponent part and a fractional part. Can be signed or unsigned .
*'''Fixed-point''' - similar to floating-point, but has fixed number of digits after the decimal point [http://en.wikipedia.org/wiki/Fixed-point_arithmetic]. They are used in processors or representing base 2 and base 10 fractional values where there is no Floating point unit.
*'''Boolean''' - used to represent logical values used for comparisons. Typically hold either of 2 values - true/false. Can also be represented as integers. Can be stored in a single bit, but typically stored as a byte.


== Primitive data types in C++ ==
The [http://en.wikipedia.org/wiki/Primitive_data_type primitive data types] refer to the built-in data types which are supported by the programming language. Often 'data types' and 'primitive data types' are used interchangeably. But not all data types are primitive. Programming languages have some non-primitive data types or derived data types which are provided by the language by making use of its primitive data types.
[http://en.wikipedia.org/wiki/C%2B%2B C++] is a statically typed, objected oriented programming language. It is widely used on a lot of hardware and software platforms. As C++ just adds object oriented features and a few other enhancements to C, the primitive data types that it provides are same as those provided by C[http://en.wikipedia.org/wiki/C%2B%2B]. They are described below [http://en.cppreference.com/w/cpp/language/types].
 
The common built-in data types or primitive data types are integers, floating point numbers, characters, strings and boolean.
* Integers - Integers represent the whole numbers which can be positive or negative or zero, e.g. 9999, 0, -25, etc.
* Floating point numbers - Floating point numbers represent the numbers which are fractions or contain floating-decimal points, e.g. -3.002, 2.5, 22.0, etc.
* Characters - Characters represent any single letter, number, space, punctuation mark, or symbol that can be typed on a computer, e.g. 'a', '9', ' ', '!' , '\n', etc.
* Strings - Strings represent the sequences of characters or simply any text, e.g. "Hello!", "9 am to 6 pm", etc.
* Booleans - Booleans represent the true or false values. Sometimes, instead of true and false, 1 and 0 are used to represent the boolean values.
 
Many [http://en.wikipedia.org/wiki/Object-oriented_programming object-oriented programming] languages provide support for primitive data types while some object-oriented programming languages provide support for primitive objects along with primitive types.
 
== Definition ==
 
Primitive objects refer to the objects of built-in classes which provide more functionality than the primitive types. Some object-oriented programming languages provide support for only primitive objects (i.e., in such languages all primitive types are objects).
 
Different object-oriented programming languages implement these primitive data types and primitive objects in a different manner.
 
== Primitive objects in different OO languages  ==
 
=== C++===
[http://en.wikipedia.org/wiki/C%2B%2B C++] is a statically typed, objected oriented programming language. It is widely used on a lot of hardware and software platforms. As C++ just adds object oriented features and a few other enhancements to C, the primitive data types that it provides are same as those provided by C<ref>http://en.wikipedia.org/wiki/C%2B%2B C++ an extension of C</ref>. They are described below <ref>http://en.cppreference.com/w/cpp/language/types List of C++ data types</ref>.


{| border="1" style="border-spacing: 0" cellpadding="5"
{| border="1" style="border-spacing: 0" cellpadding="5"
Line 31: Line 44:
|-
|-
| wchar_t
| wchar_t
| used for storing compiler-defined wide characters and unicode characters [http://en.wikipedia.org/wiki/Wide_character]
| used for storing compiler-defined wide characters and unicode characters <ref>http://en.wikipedia.org/wiki/Wide_character Wide Character in C++ </ref>
| compiler defined
| compiler defined
| compiler defined
| compiler defined
Line 43: Line 56:
| double precision floating-point
| double precision floating-point
| 8 bytes
| 8 bytes
| +/–1.7 * 10^308 [http://msdn.microsoft.com/en-us/library/e02ya398(v=vs.80).aspx]
| +/–1.7 * 10^308
|-
|-
| bool
| bool
Line 51: Line 64:
|-
|-
| void
| void
| generic identifier that does not identify type [http://sparkcharts.sparknotes.com/cs/cplusplus/section2.php]
| generic identifier that does not identify type  
| Does not exist
| Does not exist
| Does not exist
| Does not exist
|}
|}


C++ allows variables of any of these data types to be created and also supports using these data types to construct complex data types like structures and classes. C++ also provides ''pointers'' that can be used to store the address of a variable of any simple or complex data type.
C++ allows variables of any of these data types to be created and also supports using these data types to construct complex data types like structures and classes. C++ also allows ''pointers'' that can be used to store the address of a variable of any simple or complex data type.


== Primitive data types in Java ==
=== Java ===
There is a certain group of data types that is used very frequently by the programmer. These types are included in the Java language as the primitive data types.These data types have a fixed size which does not change from one system to another and adds to the portability feature of java. There are 8 primitive data types defined in java which are as follows:[http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html]
There are 8 primitive data types defined in java which are as follows<ref>http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html Java data types</ref>:
{| border="1" style="border-spacing: 0" cellpadding="5"
{| border="1" style="border-spacing: 0" cellpadding="5"
! align="left"|Name
! align="left"|Name
Line 124: Line 137:
| '\u0000'
| '\u0000'
|}
|}
Besides these 8 primitive data types java provides support to characterstrings through Java.lang.String class. String is not a primitive datatype but its usage and functionality makes us think of it being so.


== Primitive data types in C# ==
Besides these 8 primitive data types java provides support to character strings through Java.lang.String class. String is not a primitive datatype but its usage and functionality makes us think of it being so. One of the major differences in Java from the other languages is that,the size of variables of these primitive types do not vary from one system to another, ie, it is not machine/architecture dependent. Also, Java does not allow numeric values to be stored unsigned<ref>http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Java_Primitive_Types.html Java Primitive datatypes </ref>.
 
Also, for each of these primitive types, Java provides [http://en.wikipedia.org/wiki/Primitive_wrapper_class wrapper classes] to create primitive objects which wrap the primitive data values. A wrapper  not only contains the primitive data value, but it also defines properties and methods that can be used to manipulate that data. In Java, the primitive values are not implicitly converted to primitive objects. Instead, methods are provided for doing explicit conversion.
The primitive objects are stored on [http://www.maxi-pedia.com/what+is+heap+and+stack heap] in memory while the variables containing primitive values are stored on [http://www.maxi-pedia.com/what+is+heap+and+stack stack].<ref>http://www.informit.com/articles/article.aspx?p=31755&seqNum=8 Stack and Heap memory</ref>
 
Example:
    int i = 10;
    int ii = 20;
    Integer I = new Integer(i);
    Integer II = new Integer(ii);
    System.out.println(I+II);           
    System.out.println(I.equals(II));   
 
Output:
    30
    false
 
 
To find out if these wrapper classes are primitive or not, we can use the isPrimitive() method.
 
    System.out.println(INTEGER.TYPE.isPrimitive());
    System.out.println(BOOLEAN.TYPE.isPrimitive());
 
Output:
    true
    true
 
 
In Java, the comparison operations work in the same way on the primitive objects as well as any other class objects but different on the primitive types. The == operator when used on objects checks whether they refer to the same object but when used on variables of primitive types checks whether they contain the same value.<ref>http://leepoint.net/notes-java/data/expressions/22compareobjects.html Comparisons in Java</ref>
 
Example:
    int i = 10;
    int ii = 10;
    Integer I = new Integer(i);
    Integer II = new Integer(ii);
    System.out.println(I==II);           
    System.out.println(i==ii);
 
Output:
    false
    true
 
===C# ===
C# is a statically-typed object oriented programming language. C# provides all the data types that are available in Java, and adds support for unsigned numerals and a new 128-bit high-precision floating-point type. All primitive data types in C# are objects in the System namespace.
C# is a statically-typed object oriented programming language. C# provides all the data types that are available in Java, and adds support for unsigned numerals and a new 128-bit high-precision floating-point type. All primitive data types in C# are objects in the System namespace.
The various primitive data types in C# are defined below:[http://msdn.microsoft.com/en-us/library/ms228360(v=vs.80).aspx]
The various primitive data types in C# are defined below<ref>http://msdn.microsoft.com/en-us/library/ms228360(v=vs.80).aspx C# data types </ref>:
{| border="1" style="border-spacing: 0" cellpadding="5"
{| border="1" style="border-spacing: 0" cellpadding="5"
! align="left"| Name  
! align="left"| Name  
Line 227: Line 281:
|}
|}


== Primitive data types/objects in Ruby ==
[http://en.wikipedia.org/wiki/C_Sharp_%28programming_language%29 C#] is a [http://en.wikipedia.org/wiki/Strong_typing strongly typed] language, where it is necessary to declare the data type of a variable and also be aware of the data type conversion. C# provides a significant number of primitive data types.<ref>http://condor.depaul.edu/sjost/ndp/notes/cs1/CSDatatypes.htm C# Primitive Datatypes</ref><ref>http://www.java2s.com/Tutorial/CSharp/0040__Data-Type/PrimitivesinC.htm Primitives in C#</ref>
Ruby is a multi-paradigm programming language. It is dynamically typed, and allows to be programmed procedural, object-oriented or functional[http://www.cse.iitb.ac.in/~cs701/old/beamer/Closures.pdf]. As it is also a ''pure'' object oriented programming language, even the basic inbuilt types like integer and string and even constants are represented as objects. There are a lot of inbuilt classes that are provided by Ruby[http://ruby-doc.org/docs/ProgrammingRuby/html/builtins.html]. These classes differ in some extent to their counterparts in other languages. Having all the basic types as classes allows a lot of methods to be executed on them that reduces the amount of code that needs to be newly written. Some of the basic classes are:
 
Because C# represents all primitive data types as objects, it is possible to call an object method on a primitive data type. For example:
    static void Main()
    {
        int x = 7;
        object o = x;
        System.Console.WriteLine(o.ToString());
    }
 
Some data types (e.g. Decimal and String) can appear like primitives at first sight, but are actually not. So it is important to exercise caution before making such assumptions. To test whether a particular type is a primitive or not you can use the property Type.IsPrimitive.
 
Consider the following example:
 
    if (t.IsPrimitive)    // where t is the type
    {
        // Is Primitive
    } else if (t == typeof(Decimal))
    {
        // Is Decimal
    } else if (t == typeof(String))
    {
        // Is String
    } else
    {
        // Other type
    }
 
===JavaScript===
 
There are 5 primitive data types in [http://en.wikipedia.org/wiki/JavaScript JavaScript]: string, number, boolean, null and undefined. <ref>http://oreilly.com/javascript/excerpts/learning-javascript/javascript-datatypes-variables.html JavaScript Data Types and Variables</ref>
 
For string, number and boolean values, there are corresponding classes just like in Java to create primitive objects which wrap the primitive values.
 
{| class="wikitable"
|+
|-
! Primitive Type !! Wrapper Class
|-
| string || String
|-
| number|| Number
|-
| boolean || Boolean
|}
 
In JavaScript, the primitive value is implicitly converted to a primitive object whenever someone tries to access a property or invoke a method on the primitive value and the primitive object is used in place of the primitive value. Since the object contains properties and methods, the use of primitive value as an object succeeds. After the property is accessed or the method is processed, the primitive object is no longer needed and hence discarded. The same is true for the other primitive types and their corresponding primitive objects.
 
Example:
 
    var upperCaseString = "APPLE";
    var lowerCaseString = upperCaseString.toLowerCase();  // assigns string "apple" to lowerCaseString
    var s = "Hello"
    var len = s.length;                                  // assigns value 5 to len
 
===Ruby ===
Since [http://en.wikipedia.org/wiki/Ruby_%28programming_language%29 Ruby] is a [http://www.jvoegele.com/software/langcomp.html pure object oriented] language, everything in Ruby is an object. Hence, all primitive types such as integers, floating point numbers, strings, are objects of a built-in class.<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/builtins.html Classes in Ruby</ref> Some of the basic classes are:


{| border="1" style="border-spacing: 0" cellpadding="5"
{| border="1" style="border-spacing: 0" cellpadding="5"
Line 236: Line 346:
|-
|-
| Integer
| Integer
| base class for FixNum and BigNum [http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_integer.html]
| base class for FixNum and BigNum <ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_integer.html Integer in Ruby </ref>
| depends on FixNum and BigNum
| depends on FixNum and BigNum
|-
|-
| FixNum
| FixNum
| store integer values that fit in a native machine word [http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_integer.html] (for 32-bit systems)
| store integer values that fit in a native machine word<ref> http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_fixnum.html Fixnum</ref>
| ± 2^30
| ± 2^30 (for 32-bit systems)
|-  
|-  
| BigNum
| BigNum
| store Integer values larger than FixNum[http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_bignum.html] (for 32-bit systems)
| store Integer values larger than FixNum<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_bignum.html Bignum</ref>
| values > 2^30
| values > 2^30 (for 32-bit systems)
|-
|-
| String
| String
| sequence of characters/bytes [http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html]
| sequence of characters/bytes<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html String </ref>
| Does not exist.  
| Does not exist.  
|-
|-
| Float
| Float
| real numbers with double precision floating point precision[http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_float.html]
| real numbers with double precision floating point precision<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_float.html Float </ref>
| ± 1.7976 * 10^308
| ± 1.7976 * 10^308 (for 32-bit systems)
|-
|-
| TrueClass
| TrueClass
| represents logical ''true'' value[http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_trueclass.html]
| represents logical ''true'' value<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_trueclass.html TrueClass </ref>
| true
| true
|-
|-
| FalseClass
| FalseClass
| represents logical ''false'' value[http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_falseclass.html]
| represents logical ''false'' value<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_falseclass.html FalseClass</ref>
| false
| false
|}
|}


There are a various other inbuilt classes that are provided by Ruby. Those classes can be constructed by combining one or more of the above given primitive classes. As these are existing classes, there are a lot of helper methods that allow easy calculations and operations on the objects of these classes. Some of these classes also have inbuilt iterator methods that allow the values to be modified automatically for using in loops. As with many other programming languages, some of these objects take up different size (and hence range) on different architectures. These existing classes are also editable and allows to override or add new functionality to them for custom use in the application.
All integers are primitive objects of either class [http://corelib.rubyonrails.org/classes/Fixnum.html Fixnum] or [http://corelib.rubyonrails.org/classes/Bignum.html Bignum]. A numeric literal with a decimal point and/or an exponent is a primitive object of [http://corelib.rubyonrails.org/classes/Float.html Float]. Single quoted literals and double quoted literals are primitive objects of [http://corelib.rubyonrails.org/classes/String.html String].
 
Example:
 
    puts 10.class
    puts 7.45.class
    puts 'hi'.class
    puts "hello".class
 
Output:
 
    Fixnum
    Float
    String
    String
 
This indicates that 10 is converted into an object of type Fixnum, 7.45 is converted into an object of type Float, 'hi' and "hello" are both converted into an object of type String.
 
Since all primitive types in Ruby are objects, we should be able to call methods of the Object class on them. Let us demonstrate the same for integer and float using the following example:
 
    a=10
    puts a.to_f 
    b=20.5
    puts b.to_i
 
Output:
    10.0
    20
 
==Advantages of using primitive data types==
The various advantages of using primitive data types are as follows:
=== Efficiency ===
Use of primitive data types takes less time to execute than a similar program that executes using object types. This is mainly because, when using object types, a lot of function calls are done implicitly to get the variables necessary for the operation. Consider the following example,
 
<pre>
Integer a = new Integer(20);
Integer b = new Integer(30);
Integer c = a + b;
</pre>
 
When <code>a+b</code> is executed, the line implicitly changes to <code>c.valueOf(a.intValue() + b.intValue())</code> on the right hand side<ref>http://chaoticjava.com/posts/autoboxing-tips/ Autoboxing in Java</ref>. This increases the number of function calls and so takes up more time to execute. This is the case for all objects. This delay is not present when primitive data types are used as the actual data is fetched from memory instead of calling another function to retrieve it.
 
Using primitive data types is much more efficient way of programming than programming using objects<ref>http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance%5Fissue autoboxing performance issues</ref>. For example, in Java when we use boxing in a loop it causes certain performance issues and is inefficient compared to using the primitive types directly. For more details and a sample program see [http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance%5Fissue this]. Also, the discussion in this [http://stackoverflow.com/questions/8001988/where-and-when-the-use-of-primitive-data-types-in-java-is-effectively-appropriat page] describes just how the use of wrapper classes in Java takes up more memory during run time than when using primitive objects. It also provides sample programs to see this difference in our systems.
 
=== Simplicity ===
Working with primitive data types is more intuitive.
 
Example:
1. As a counter in a loop. Using objects in this place would make the program difficult to understand and tedious for the programmer.
(int i=0;i<10;i++)
 
2. In conditional statements.
 
if(x > max)
    max = x;
 
== Disadvantages ==
 
=== Lack of inheritance capability ===
The primitive data types in languages such as Java cannot be inherited to create further subtypes as the wrapper classes like Integer, Float, etc are all final. Some applications that use OO languages might require more functionality than what is provided by the primitive datatype. For example, in Java, some of the composite data type like ArrayList, can be extended to add new functions like <code>sum</code>,etc to be used in the application.
 
<pre>
public class MyArrayList<E> extends ArrayList<e> {
}
</pre>
 
This provides a lot of customization options that help write more cleaner code. As an exception, the language SmallTalk allows even the basic primitive types to be inherited and modify the operations that can be performed on them.
 
=== Not Scalable ===
Using primitive datatypes is '''not scalable '''enough for real time applications. For example, a real time application would like to work with a large number of similar or varied type of data. To use primitive types for this scenario would involve creating a lot of variables and maintaining the state of all these variables, which is hard to do<ref>http://wiki.answers.com/Q/What_are_the_advantages_of_arrays_in_java arrays more scalable than primitive types</ref>. Composite objects like arrays or lists can provide easier representation and management of data. For example, to represent a list of variables,
 
<pre>
char a[5] = {'c','a','d','f',h'};
</pre>
 
Representing data in this way, allows easy access of the data as a[0], a[1], etc. This type of access by using a single variable to refer to multiple variables and memory locations allows performing similar operations on all the variables together (using loops or similar constructs).
 
=== Utility Functions ===
The presence of utility functions for composite objects allows a lot of operations to be performed on the data. For example in Java, the ArrayLists class allows any type of data to be stored in them and provides a lot of utility functions. Operations like searching within the list can be performed by simply calling a utility function available, where as the user would have had to write explicit functions had primitive types been used. The generic classes in Java donot allow primitive datatypes to be used as parameters. So, to use an ArrayList of integers in Java, we should use the wrapper class of int (Integer) instead.
 
<pre>
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5); // Though '5' is given as a primitive type, java performs Autoboxing to promote it to Integer Object.
list.add(4);
list.add(3);
list.add(2);
list.add(1);
System.out.println(list.contains(5));
</pre>
 
Output:
true
 
In languages that do not support pointers, such collection objects also do not restrict the user from having a fixed number of entries<ref> http://stackoverflow.com/questions/4842883/are-there-reasons-to-prefer-arrays-over-arraylists ArrayLists better than Arrays </ref>. The number of entries in such a list can vary dynamically. Performing aggregate operations on a bunch of values is also much easier when composite objects are used. For example, Usage of the Collections framework present in Java allows to perform a lot of operations like sorting the values present in the collection. As the sort operations that are pre-implemented in the Collection framework are in-built java functions, they are extremely fast (order of nlog n).
 
<pre>
Collections.sort(list);
System.out.println(list);
</pre>
 
Output:
[1, 2, 3, 4, 5]
 
Exceptions to this are languages like Ruby, which treat all the basic types as objects and provide utility functions for all of them.


== Advantages and Disadvantages ==
=== Null Values ===  
In this section we discuss the various advantages and disadvanges of using the primitive data types over the corresponding object types.
Primitive data types do not allow to hold '''null values'''. So they cannot be used when a check for null value is essential<ref>http://stackoverflow.com/questions/2509025/when-to-use-primitive-and-when-reference-types-in-java When and when not to use primitives</ref>.


=== Advantages ===
=== Unexpected results due to method overriding ===  
The various advantages that use of primitive data type offers are as follows:
There are certain examples such as [http://blog.vishnuiyengar.com/2009/09/primitive-obsession-in-ruby-aka-not.html this], which show that overriding inbuilt methods such as == and eql? can lead to unexpected results.
*Ease of use: Using primitive data types is much more efficient way of programming then programming using objects. For example, in Java when we use boxing in a loop it causes certain performance issues and is inefficient compared to using the primitive types directly. For more details and a sample program see [http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance%5Fissue].


== Conclusion ==
== Conclusion ==
Primitive objects that are provided in object oriented programming languages have their own advantages and disadvantages. Though using primitive data types in most languages reduces the degree of customization possible, they provide a better performance and ease of use to compensate. The extent to which a primitive data type can be used efficiently depends on the application and the programming language used for the application.


== References ==
== References ==
<references/>

Latest revision as of 21:16, 21 September 2012

Primitive objects in object-oriented languages - based on the wiki page from previous year

Introduction

In any programming language, the data type refers to the class of data which contains specific type or range of values. Data types are used along with variables used in the program. The data type tells us what kind of values the variable can store, what is the range of the values and how much space the values take in memory etc.

The primitive data types refer to the built-in data types which are supported by the programming language. Often 'data types' and 'primitive data types' are used interchangeably. But not all data types are primitive. Programming languages have some non-primitive data types or derived data types which are provided by the language by making use of its primitive data types.

The common built-in data types or primitive data types are integers, floating point numbers, characters, strings and boolean.

  • Integers - Integers represent the whole numbers which can be positive or negative or zero, e.g. 9999, 0, -25, etc.
  • Floating point numbers - Floating point numbers represent the numbers which are fractions or contain floating-decimal points, e.g. -3.002, 2.5, 22.0, etc.
  • Characters - Characters represent any single letter, number, space, punctuation mark, or symbol that can be typed on a computer, e.g. 'a', '9', ' ', '!' , '\n', etc.
  • Strings - Strings represent the sequences of characters or simply any text, e.g. "Hello!", "9 am to 6 pm", etc.
  • Booleans - Booleans represent the true or false values. Sometimes, instead of true and false, 1 and 0 are used to represent the boolean values.

Many object-oriented programming languages provide support for primitive data types while some object-oriented programming languages provide support for primitive objects along with primitive types.

Definition

Primitive objects refer to the objects of built-in classes which provide more functionality than the primitive types. Some object-oriented programming languages provide support for only primitive objects (i.e., in such languages all primitive types are objects).

Different object-oriented programming languages implement these primitive data types and primitive objects in a different manner.

Primitive objects in different OO languages

C++

C++ is a statically typed, objected oriented programming language. It is widely used on a lot of hardware and software platforms. As C++ just adds object oriented features and a few other enhancements to C, the primitive data types that it provides are same as those provided by C<ref>http://en.wikipedia.org/wiki/C%2B%2B C++ an extension of C</ref>. They are described below <ref>http://en.cppreference.com/w/cpp/language/types List of C++ data types</ref>.

Name Description Size Range
int Basic numerical data. Can have modifiers that vary size and range. 4 bytes -2,147,483,648 to 2,147,483,647
char Can hold one character of data like an alphabet, number, or symbol represented in ASCII 1 byte -128 to 127
wchar_t used for storing compiler-defined wide characters and unicode characters <ref>http://en.wikipedia.org/wiki/Wide_character Wide Character in C++ </ref> compiler defined compiler defined
float single precision floating-point 4 bytes ± 3.402,823,4 * 10^38
double double precision floating-point 8 bytes +/–1.7 * 10^308
bool represents logical values 1 byte true/false
void generic identifier that does not identify type Does not exist Does not exist

C++ allows variables of any of these data types to be created and also supports using these data types to construct complex data types like structures and classes. C++ also allows pointers that can be used to store the address of a variable of any simple or complex data type.

Java

There are 8 primitive data types defined in java which are as follows<ref>http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html Java data types</ref>:

Name Description Size(in bits) Range Usage Default Value
byte Signed two's complement integer 8 bits -128 to 127 This datatype can be used in arrays where there is a space constraint to save memory. 0
short Signed two's complement integer 16 bits -32,768 to 32,767 This datatype can also be used to save memory in large arrrays. 0
int signed two's complement integer 32 bits -2,147,483,648 to 2,147,483,647 This datatype is generally the default datatype for all the numbers we use in our program. 0
long signed two's complement integer 64 bits -9,223,372,036,854,775,808 to 9,223,373,036,854,775,807 This type is used when we require a value that is outside the range of values provided by int. 0L
float Single-precision IEEE 754 floating point 32 bits 32-bit IEEE 754 floating-point numbers. Use this datatype to save memory in large arrays. 0.0f
double Double-precision 64-bit IEEE 754 floating point 64 bits 64-bit IEEE 754 floating-point numbers. This data type is generally the default for decimal values. 0.0d
boolean Boolean 1- bit false, true Use this data type for flags that track a true or false condition. false
char a char is a single 16-bit character encoded using Unicode 16 bit Unicode character \u0000(0) through unicode character \uffff(65,535) This type is used to define single characters. '\u0000'

Besides these 8 primitive data types java provides support to character strings through Java.lang.String class. String is not a primitive datatype but its usage and functionality makes us think of it being so. One of the major differences in Java from the other languages is that,the size of variables of these primitive types do not vary from one system to another, ie, it is not machine/architecture dependent. Also, Java does not allow numeric values to be stored unsigned<ref>http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Java_Primitive_Types.html Java Primitive datatypes </ref>.

Also, for each of these primitive types, Java provides wrapper classes to create primitive objects which wrap the primitive data values. A wrapper not only contains the primitive data value, but it also defines properties and methods that can be used to manipulate that data. In Java, the primitive values are not implicitly converted to primitive objects. Instead, methods are provided for doing explicit conversion. The primitive objects are stored on heap in memory while the variables containing primitive values are stored on stack.<ref>http://www.informit.com/articles/article.aspx?p=31755&seqNum=8 Stack and Heap memory</ref>

Example:

   int i = 10;
   int ii = 20;
   Integer I = new Integer(i);
   Integer II = new Integer(ii);
   System.out.println(I+II);            
   System.out.println(I.equals(II));    

Output:

   30
   false


To find out if these wrapper classes are primitive or not, we can use the isPrimitive() method.

   System.out.println(INTEGER.TYPE.isPrimitive());
   System.out.println(BOOLEAN.TYPE.isPrimitive());

Output:

   true
   true


In Java, the comparison operations work in the same way on the primitive objects as well as any other class objects but different on the primitive types. The == operator when used on objects checks whether they refer to the same object but when used on variables of primitive types checks whether they contain the same value.<ref>http://leepoint.net/notes-java/data/expressions/22compareobjects.html Comparisons in Java</ref>

Example:

   int i = 10;
   int ii = 10;
   Integer I = new Integer(i);
   Integer II = new Integer(ii);
   System.out.println(I==II);            
   System.out.println(i==ii);

Output:

   false
   true

C#

C# is a statically-typed object oriented programming language. C# provides all the data types that are available in Java, and adds support for unsigned numerals and a new 128-bit high-precision floating-point type. All primitive data types in C# are objects in the System namespace. The various primitive data types in C# are defined below<ref>http://msdn.microsoft.com/en-us/library/ms228360(v=vs.80).aspx C# data types </ref>:

Name .NET Class Size Description Range
byte System.Byte 8 bits 8-bit unsigned integral type. 0 to 255
sbyte System.SByte 8 bits signed two's complement integer -128 to 127
short System.Int16 16 bits 16-bit signed integral type. -32,768 to 32,767
ushort System.UInt16 16 bits 16-bit unsigned integral type. 0 to 65,535
int Int32 32 bits signed two's complement integer -2,147,483,648 to 2,147,483,647
uint System.Int32 32 bits 32-bit signed integral type. 0 to 4,294,967,295
long System.Int64 64 bits 64-bit signed integral type. -9,223,372,036,854,775,808 to 9,223,373,036,854,775,807
ulong System.UIint64 64 bits 64-bit unsigned integral type. 0 to 18,446,744,073,709,551,615
float System.Single 32 bits Single-precision floating-point type. -3.402823e38 to 3.02823e38
double System.Double 64 bits Double-precision floating-point type. -1.79769313486232e308 to 1.79769313486232e308
bool System.Boolean 1 bit Logical Boolean type false, true
char System.Char 16 bits A 16-bit Unicode character. Unicode character \u0000 through unicode character \uffff
object System.Object N/A Ultimate base type of all other types. N/A
string System.String N/A A sequence of Unicode characters. N/A
decimal System.Decimal 128 Precise decimal with 28 significant digits. ±1.0 × 10e−28 to ±7.9 × 10e28

C# is a strongly typed language, where it is necessary to declare the data type of a variable and also be aware of the data type conversion. C# provides a significant number of primitive data types.<ref>http://condor.depaul.edu/sjost/ndp/notes/cs1/CSDatatypes.htm C# Primitive Datatypes</ref><ref>http://www.java2s.com/Tutorial/CSharp/0040__Data-Type/PrimitivesinC.htm Primitives in C#</ref>

Because C# represents all primitive data types as objects, it is possible to call an object method on a primitive data type. For example:

   static void Main()
   {
       int x = 7;
       object o = x;
       System.Console.WriteLine(o.ToString());
   }

Some data types (e.g. Decimal and String) can appear like primitives at first sight, but are actually not. So it is important to exercise caution before making such assumptions. To test whether a particular type is a primitive or not you can use the property Type.IsPrimitive.

Consider the following example:

   if (t.IsPrimitive)    // where t is the type
   {
       // Is Primitive
   } else if (t == typeof(Decimal))
   {
       // Is Decimal
   } else if (t == typeof(String))
   {
       // Is String
   } else
   {
       // Other type
   }

JavaScript

There are 5 primitive data types in JavaScript: string, number, boolean, null and undefined. <ref>http://oreilly.com/javascript/excerpts/learning-javascript/javascript-datatypes-variables.html JavaScript Data Types and Variables</ref>

For string, number and boolean values, there are corresponding classes just like in Java to create primitive objects which wrap the primitive values.

Primitive Type Wrapper Class
string String
number Number
boolean Boolean

In JavaScript, the primitive value is implicitly converted to a primitive object whenever someone tries to access a property or invoke a method on the primitive value and the primitive object is used in place of the primitive value. Since the object contains properties and methods, the use of primitive value as an object succeeds. After the property is accessed or the method is processed, the primitive object is no longer needed and hence discarded. The same is true for the other primitive types and their corresponding primitive objects.

Example:

   var upperCaseString = "APPLE";
   var lowerCaseString = upperCaseString.toLowerCase();  // assigns string "apple" to lowerCaseString 
   var s = "Hello"
   var len = s.length;                                   // assigns value 5 to len

Ruby

Since Ruby is a pure object oriented language, everything in Ruby is an object. Hence, all primitive types such as integers, floating point numbers, strings, are objects of a built-in class.<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/builtins.html Classes in Ruby</ref> Some of the basic classes are:

Name Description Range
Integer base class for FixNum and BigNum <ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_integer.html Integer in Ruby </ref> depends on FixNum and BigNum
FixNum store integer values that fit in a native machine word<ref> http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_fixnum.html Fixnum</ref> ± 2^30 (for 32-bit systems)
BigNum store Integer values larger than FixNum<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_bignum.html Bignum</ref> values > 2^30 (for 32-bit systems)
String sequence of characters/bytes<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_string.html String </ref> Does not exist.
Float real numbers with double precision floating point precision<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_float.html Float </ref> ± 1.7976 * 10^308 (for 32-bit systems)
TrueClass represents logical true value<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_trueclass.html TrueClass </ref> true
FalseClass represents logical false value<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/ref_c_falseclass.html FalseClass</ref> false

All integers are primitive objects of either class Fixnum or Bignum. A numeric literal with a decimal point and/or an exponent is a primitive object of Float. Single quoted literals and double quoted literals are primitive objects of String.

Example:

   puts 10.class
   puts 7.45.class
   puts 'hi'.class
   puts "hello".class

Output:

   Fixnum
   Float
   String
   String

This indicates that 10 is converted into an object of type Fixnum, 7.45 is converted into an object of type Float, 'hi' and "hello" are both converted into an object of type String.

Since all primitive types in Ruby are objects, we should be able to call methods of the Object class on them. Let us demonstrate the same for integer and float using the following example:

   a=10
   puts a.to_f  
   b=20.5
   puts b.to_i

Output:

   10.0
   20

Advantages of using primitive data types

The various advantages of using primitive data types are as follows:

Efficiency

Use of primitive data types takes less time to execute than a similar program that executes using object types. This is mainly because, when using object types, a lot of function calls are done implicitly to get the variables necessary for the operation. Consider the following example,

Integer a = new Integer(20);
Integer b = new Integer(30);
Integer c = a + b;

When a+b is executed, the line implicitly changes to c.valueOf(a.intValue() + b.intValue()) on the right hand side<ref>http://chaoticjava.com/posts/autoboxing-tips/ Autoboxing in Java</ref>. This increases the number of function calls and so takes up more time to execute. This is the case for all objects. This delay is not present when primitive data types are used as the actual data is fetched from memory instead of calling another function to retrieve it.

Using primitive data types is much more efficient way of programming than programming using objects<ref>http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance%5Fissue autoboxing performance issues</ref>. For example, in Java when we use boxing in a loop it causes certain performance issues and is inefficient compared to using the primitive types directly. For more details and a sample program see this. Also, the discussion in this page describes just how the use of wrapper classes in Java takes up more memory during run time than when using primitive objects. It also provides sample programs to see this difference in our systems.

Simplicity

Working with primitive data types is more intuitive.

Example: 1. As a counter in a loop. Using objects in this place would make the program difficult to understand and tedious for the programmer.

(int i=0;i<10;i++)

2. In conditional statements.

if(x > max)
    max = x;

Disadvantages

Lack of inheritance capability

The primitive data types in languages such as Java cannot be inherited to create further subtypes as the wrapper classes like Integer, Float, etc are all final. Some applications that use OO languages might require more functionality than what is provided by the primitive datatype. For example, in Java, some of the composite data type like ArrayList, can be extended to add new functions like sum,etc to be used in the application.

public class MyArrayList<E> extends ArrayList<e> {
}

This provides a lot of customization options that help write more cleaner code. As an exception, the language SmallTalk allows even the basic primitive types to be inherited and modify the operations that can be performed on them.

Not Scalable

Using primitive datatypes is not scalable enough for real time applications. For example, a real time application would like to work with a large number of similar or varied type of data. To use primitive types for this scenario would involve creating a lot of variables and maintaining the state of all these variables, which is hard to do<ref>http://wiki.answers.com/Q/What_are_the_advantages_of_arrays_in_java arrays more scalable than primitive types</ref>. Composite objects like arrays or lists can provide easier representation and management of data. For example, to represent a list of variables,

char a[5] = {'c','a','d','f',h'}; 

Representing data in this way, allows easy access of the data as a[0], a[1], etc. This type of access by using a single variable to refer to multiple variables and memory locations allows performing similar operations on all the variables together (using loops or similar constructs).

Utility Functions

The presence of utility functions for composite objects allows a lot of operations to be performed on the data. For example in Java, the ArrayLists class allows any type of data to be stored in them and provides a lot of utility functions. Operations like searching within the list can be performed by simply calling a utility function available, where as the user would have had to write explicit functions had primitive types been used. The generic classes in Java donot allow primitive datatypes to be used as parameters. So, to use an ArrayList of integers in Java, we should use the wrapper class of int (Integer) instead.

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5); // Though '5' is given as a primitive type, java performs Autoboxing to promote it to Integer Object.
list.add(4);
list.add(3);
list.add(2);
list.add(1);
System.out.println(list.contains(5));

Output:

true

In languages that do not support pointers, such collection objects also do not restrict the user from having a fixed number of entries<ref> http://stackoverflow.com/questions/4842883/are-there-reasons-to-prefer-arrays-over-arraylists ArrayLists better than Arrays </ref>. The number of entries in such a list can vary dynamically. Performing aggregate operations on a bunch of values is also much easier when composite objects are used. For example, Usage of the Collections framework present in Java allows to perform a lot of operations like sorting the values present in the collection. As the sort operations that are pre-implemented in the Collection framework are in-built java functions, they are extremely fast (order of nlog n).

Collections.sort(list);
System.out.println(list);

Output:

[1, 2, 3, 4, 5]

Exceptions to this are languages like Ruby, which treat all the basic types as objects and provide utility functions for all of them.

Null Values

Primitive data types do not allow to hold null values. So they cannot be used when a check for null value is essential<ref>http://stackoverflow.com/questions/2509025/when-to-use-primitive-and-when-reference-types-in-java When and when not to use primitives</ref>.

Unexpected results due to method overriding

There are certain examples such as this, which show that overriding inbuilt methods such as == and eql? can lead to unexpected results.

Conclusion

Primitive objects that are provided in object oriented programming languages have their own advantages and disadvantages. Though using primitive data types in most languages reduces the degree of customization possible, they provide a better performance and ease of use to compensate. The extent to which a primitive data type can be used efficiently depends on the application and the programming language used for the application.

References

<references/>