View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

Data Types in Java: Primitive & Non-Primitive Data Types

By Rohan Vats

Updated on May 26, 2025 | 13 min read | 19.92K+ views

Share:

Latest Update: Introduced in Java 24, JEP 450 reduces the size of object headers on 64-bit systems. This enhancement improves memory efficiency and supports better data locality, making it particularly useful for applications dealing with large data sets or high-throughput systems, such as AI workloads.

Data types in Java are the building blocks of any Java program, defining the kind of data a variable can hold. They are crucial because Java is a strongly typed language, meaning every variable must have a defined type, ensuring type safety, efficient memory usage, and fewer runtime errors.

In this blog, we’ll explore Java’s primitive data types and non-primitive data types, covering their features, memory use, value ranges, and best use cases. 

Confused about which Java data type to use and when? Learn through upGrad’s Online Software Development Courses doing 5+ capstone projects with industry experts from top universities. Enroll today!

Data Types in Java: At a Glance

Here is a quick comparison of Java's primitive and non-primitive data types by type, size, and purpose.

Type

Size

Default Value

Range / Description

byte 1 byte (8 bits) 0 -128 to 127
short 2 bytes (16 bits) 0 -32,768 to 32,767
int 4 bytes (32 bits) 0 -2,147,483,648 to 2,147,483,647
long 8 bytes (64 bits) 0L -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
float 4 bytes (32 bits) 0.0f ~±3.4 × 10^38 (7 digits precision)
double 8 bytes (64 bits) 0.0d ~±1.7 × 10^308 (15 digits precision)
char 2 bytes (16 bits) '\u0000' 0 to 65,535 (stores a single Unicode character)
boolean 1 bit (theoretically) false true or false
String Varies null Sequence of characters; predefined class in Java
Array Varies null Collection of elements of the same type
Class Varies null User-defined blueprint for objects
Interface Varies null Abstract type used to specify method signatures

 

To meet the rising industry demand for skilled professionals, check out the following top courses that will help you sharpen your skills and get job-ready in 2025.

With an understanding of Java data types, it’s time to look at their importance in creating robust, efficient, and error-free programs.

Significance of Data Types in Java

Data types in Java determine the type of data that can be stored and the operations that can be performed on that data. Understanding data types is essential for writing efficient, error-free, and optimized Java programs. 

Here’s a breakdown of their significance:

1. Memory Allocation

  • Data types specify how much memory is required to store a value. For example, an int requires 4 bytes, while a double needs 8 bytes.
  • Choosing the correct data type helps in optimizing memory usage. For instance, if a variable is intended to hold a value between 0 and 100, using byte (which takes only 1 byte) rather than int (which takes 4 bytes) would save memory.

Choosing the right data types is just one part of writing efficient code. Learn how top developers structure memory and optimize performance in real-world projects—join upGrad’s Online AI-Drive Full Stack Development Bootcamp Program today.

2. Type Safety

  • Java is a strongly typed language, meaning that variables must be explicitly declared with a type, and the compiler enforces type constraints.
  • Type safety ensures that errors related to incompatible types (such as trying to assign a String to an int) are caught at compile-time, rather than at runtime. This helps to avoid bugs and makes the code more robust.

3. Performance Optimization

  • The choice of data type can affect the performance of a program. For example, using a smaller data type like short or byte for simple, small numbers can improve performance by reducing memory consumption.
  • Primitive types in Java are faster and more efficient than objects. For example, int operations are faster than using the Integer object (which involves extra overhead due to autoboxing).

4. Code Readability and Maintainability

  • Declaring variables with meaningful data types makes code more understandable. For example, using String for text and int for integer values clearly indicates the type of data being stored.
  • Proper use of data types helps developers understand how the data is intended to be used, making the code easier to maintain and extend.

5. Handling Different Kinds of Data

  • Data types allow Java to distinguish between various kinds of data:
    • Primitive Data Types: These include byteshortintlongfloatdoublechar, and boolean. They store simple values like numbers, characters, and booleans.
    • Reference Data Types: These include objects and arrays. Reference types point to memory locations that contain data, allowing for more complex structures and behaviors.

6. Ensuring Correct Operations

  • Data types dictate what operations are valid for a particular variable. For example:
    • You cannot perform arithmetic operations on a String type unless explicitly converting it to a numeric type.
    • You cannot assign a boolean to an int because they represent fundamentally different kinds of values.
  • Java's strong typing ensures that such operations are either prevented or forcefully managed by the compiler, reducing potential errors.

7. Type Conversion

  • Java supports type casting (explicit or implicit) between compatible data types. For instance, you can cast a float to a double, or an int to a long. However, such conversions must be done carefully to avoid data loss, particularly in narrowing conversions (e.g., double to int).
  • Proper understanding of how type conversions work is essential for working with numbers and complex data structures.

8. Garbage Collection and Memory Management

  • For reference types (like objects), the garbage collector in Java handles memory management. Knowing how data types are referenced and when they can be safely garbage collected can help optimize performance.
  • Proper usage of data types helps avoid memory leaks, as improperly used reference types can accumulate unnecessary objects, leading to inefficient memory use.

Also Read: Exploring Java Architecture: A Guide to Java's Core, JVM and JDK Architecture

To better understand Java’s approach to memory management and type safety, let’s begin with an overview of its most fundamental category: the primitive data types.

Coverage of AWS, Microsoft Azure and GCP services

Certification8 Months

Job-Linked Program

Bootcamp36 Weeks

Primitive Data Types

In Java, you use primitive data types to store simple values like numbers, characters, and boolean logic directly in memory. These types are predefined by the language and offer efficient performance without the overhead of objects. You'll find eight primitives in total, each with a specific size and purpose. 

Below are the details of primitive data types with their names, sizes, and typical use cases.

1. byte

The byte data type is the smallest integer type in Java, occupying just 1 byte (8 bits) of memory. It stores whole numbers from -128 to 127, making it ideal for memory-constrained applications or when working with raw binary data such as file I/O or network streams.

  • Declarationbyte n1 = 98;
  • Note: If you assign a value outside the byte range (e.g., 130), the compiler throws an “incompatible types” error.
byte n1 = 98;
System.out.println(n1);  // Output: 98

Ready to learn Java from scratch? Enroll in upGrad’s free Core Java Basics course. Build a solid understanding of Java, gain practical coding experience, and master key development concepts. Perfect for beginners or those looking to level up their skills. Join today!

2. short

The short data type stores whole numbers from -32,768 to 32,767 using 2 bytes (16 bits). It is larger than byte but still smaller than int, offering a balance between memory efficiency and numeric range.

  • Declarationshort n1 = 9876;

Note: Using values outside this range will trigger a compilation error.

short n1 = 9876;
System.out.println(n1);  // Output: 9876

3. int

int is the default integer type in Java, storing values between -2,147,483,648 and 2,147,483,647 using 4 bytes (32 bits). It is widely used for integer operations due to its range and performance.

  • Declarationint n1 = 987654;

Common Use: Integer arithmetic, counters, indexing, etc.

int n1 = 987654;
System.out.println(n1);  // Output: 987654

4. long

The long data type is used when an int is insufficient. It stores values from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 using 8 bytes (64 bits).

  • Declarationlong n1 = 987654321098765L;

Important: Always suffix the value with L or l to distinguish it from an int.

long n1 = 987654321098765L;
System.out.println(n1);  // Output: 987654321098765

Also Read: Types of Variables in Java: Java Variables Explained

5. float

The float type is a single-precision 32-bit IEEE 754 floating-point type. It can store fractional numbers with up to 7 digits of precision, and supports values in the range ~3.4e−38 to 3.4e+38.

  • Declarationfloat n = 98.76f;

Note: Always suffix with f or F; otherwise, it’s treated as a double.

float n = 98.76f;
System.out.println(n);  // Output: 98.76

6. double

double is a double-precision 64-bit IEEE 754 floating-point type. It supports about 15 decimal digits of precision and is the default for decimal numbers in Java.

  • Range: Approximately 1.7e−308 to 1.7e+308
  • Precision: Suitable for complex scientific calculations or any use case requiring high precision.

Example Comparison:

public class Test {
    public static void main(String[] args) {
        float a1 = 1.f / 70;
        double a2 = 1.d / 70;
        float b1 = 0;
        double b2 = 0;
        float f1 = 1f;
        double f2 = 1d;

        for (int i = 0; i < 490; i++) {
            b1 += a1;
            b2 += a2;
            if (i > 1 && i <= 50) {
                f1 *= i;
                f2 *= i;
            }
        }

        System.out.println(b1);  // Output: 6.9999795 (float)
        System.out.println(b2);  // Output: 6.999999999999978 (double)
        System.out.println(f1);  // Output: Infinity (float overflow)
        System.out.println(f2);  // Output: 3.0414093201713376E64 (double)
    }
}

Why this matters: When precision or range is critical, always prefer double over float.

7. boolean

The boolean type holds only two values: true or false, using just 1 bit of memory conceptually (though usually a byte in practice). It’s typically used for:

  • Control flow (e.g., ifwhile)
  • Status flags
  • Logical operations

Valid:

 boolean x = true;
boolean y = 5 < 10;

Invalid (causes compilation error):

 boolean x = "true"; // Invalid
boolean flag = true;
boolean b1 = false;
System.out.println(flag); // Output: true
System.out.println(b1);   // Output: false

8. char

The char type stores a single 16-bit Unicode character, supporting values from '\u0000' (0) to '\uffff' (65,535). It can hold any character from the Unicode character set, including special characters, alphabets, and symbols.

  • Declarationchar c1 = 'a';

Numeric Casting: A char can be cast to an int to get its ASCII/Unicode value, and vice versa.

char c1 = 'a';        // Output: a
char c2 = 66;         // Output: B (ASCII of 66)
System.out.println((int)c1); // Output: 97

Why "int" and "double" Are Often Preferred

  • Promotion Rules:
    • Byte, short, and char values are automatically promoted to int during arithmetic operations.
    • Float values are often promoted to double internally for greater precision.
  • Default Behavior:
    • Numeric literals are int by default.
    • Decimal literals are treated as double unless explicitly marked as float.

Because of these internal conversions and broader ranges, developers commonly use int for integers and double for decimals—ensuring compatibility, avoiding unexpected overflows, and minimizing type casting issues.

Also Read: 17 Interesting Java Project Ideas & Topics For Beginners

Next, let’s explore how Java handles more complex data structures through Non-Primitive Data Types like arrays, classes, and interfaces.

Non-Primitive Data Types

Non-primitive data types, also known as reference types, are a key feature in Java’s object-oriented architecture. Unlike primitive data types that store actual values in memory, non-primitive types store references (or memory addresses) that point to the actual objects in the heap memory. These types allow Java to represent complex data structures and behaviors beyond simple values.

1. Classes and Objects

Classes are blueprints from which objects (instances) are created. Each object stores its own state (fields) and behavior (methods).

class Bird {
    String species;
    Bird(String species) {
        this.species = species;
    }
}

Bird bird1 = new Bird("Pigeon");
System.out.println(bird1.species);  // Output: Pigeon

Sharpen your skills in object oriented programming and machine learning with upGrad’s Executive Diploma in Machine Learning and AI. Gain practical expertise and prepare for high-demand roles like AI Engineer and Machine Learning Specialist. Start learning today!

2. String

String is a predefined non-primitive type in Java, and while technically a class, it’s often treated as a “special” data type due to its frequent use and built-in language support.

  • Stores a sequence of characters.
  • Immutable: once created, a String object cannot be changed.
  • Declared using double quotes.
String greeting = "Hey There";
System.out.println(greeting);  // Output: Hey There

Despite being non-primitive, many developers refer to it as Java’s “ninth primitive” due to its syntactic ease and special treatment by the JVM.

3. Arrays

Arrays in Java are objects that store multiple values of the same data type in contiguous memory. Whether it's an array of primitives or objects, arrays are always reference types.

int[] numbers = {1, 2, 3};
String[] names = {"Alice", "Bob"};

Arrays provide length information and can be multidimensional, allowing structured data storage.

Also Read: Array in Java: Types, Operations, Pros & Cons

4. Interfaces

Interfaces define abstract contracts that classes can implement. They do not store data themselves but define method signatures for implementing classes.

interface Animal {
    void speak();
}

Interfaces are reference types and enable polymorphismabstraction, and multiple inheritance.

Also Read: 20 Most Popular Programming Languages in 2025

Key Characteristics of Non-Primitive Data Types

  1. User-Defined & Built-In Types
    Non-primitive types can be either defined by the programmer (like classes, interfaces) or provided by Java (like String, arrays). Despite being reference types, some, like String, are so integral to Java that they're often treated with special syntax and optimizations.
  2. Default Value: null
    Reference variables default to null when uninitialized, unlike primitive types which have concrete default values (e.g., 0 for intfalse for boolean).
  3. Case Sensitivity & Naming Convention
    By convention, non-primitive data types start with an uppercase letter, following Java's class naming style, while primitive types are lowercase.
  4. Memory Behavior
    All reference types generally occupy the same amount of memory on the stack (holding the reference), regardless of the object’s complexity. However, the objects themselves live on the heap, and their size varies depending on fields and internal structure.
  5. Fixed Type Association
    Once declared, a reference variable is tied to a specific type and can only reference objects of that type or compatible subtypes. Java enforces strong type-checking even with reference types.

Also Read: Learn 50 Java Projects With Source Code (2025 Edition)

Primitive vs. Non-Primitive: Key Differences

The following table highlights the key differences between primitive and non-primitive data types in Java, helping you understand how they differ in structure, behavior, and usage.

Feature

Primitive Types

Non-Primitive Types

Defined By Java (predefined) Programmer or Java library
Value Stored Actual value Reference to object in memory
Default Value Type-specific (e.g., 0, false) null
Supports Methods No Yes
Case Convention Lowercase (e.g., intboolean) Uppercase (e.g., StringBird)
Memory Allocation Stack (value-based) Stack + Heap (reference + object)
Size Varies by type Same size for reference; object size varies

Advance your career in software development with upGrad’s Professional Certificate Program in Cloud Computing and DevOps! Gain practical experience with AWS, Azure, and Google Cloud, while mastering DevOps tools like Docker and Kubernetes. Work on real-world projects to get job-ready!

Understanding Ranges and Bit-Level Representation

The range of an integer-based primitive type (like byteshortint) is determined by its size in bits.

  • For byte (8 bits), 1 bit is for the sign, leaving 7 bits for the value.
    • 27=1282^7 = 12827=128, so range is -128 to +127.
  • For short (16 bits): 215=32,7682^{15} = 32,768215=32,768, hence -32,768 to +32,767.

Java uses the IEEE 754 standard for floating-point arithmetic:

  • float:
    • 23-bit mantissa + 1 hidden bit = 24 bits
    • Approx. precision: log⁡10(224)≈7\log_{10}(2^{24}) \approx 7log10​(224)≈7 decimal digits
  • double:
    • 52-bit mantissa + 1 hidden bit = 53 bits
    • Approx. precision: log⁡10(253)≈15\log_{10}(2^{53}) \approx 15log10​(253)≈15 decimal digits

So:

  • Use float for fast, space-efficient approximations.
  • Use double for high-precision mathematical and scientific calculations.

With a solid understanding of data types in Java, explore other core Java concepts with upGrad and advance your career in software development.

Also Read: How to Code, Compile, and Run Java Projects in 2025

Become an Expert in Java with upGrad!

Data types in Java define the kind of data a variable can hold, ensuring proper memory usage and operations. Java offers two main categories: primitive types (like intcharboolean) for basic values, and non-primitive types (such as String and Arrays) for objects and collections. Understanding these types helps you write efficient, type-safe code with proper memory management.

If you're looking to strengthen your Java skills further and bridge any gaps in your knowledge, upGrad’s Software Development courses offer hands-on experience, expert mentorship, and 1:1 guidance. 

Here are some additional courses to further support your advancement in Java development.

Confused about your career in software development? Contact upGrad’s expert career counselors, who will guide you based on your goals. You can also visit a nearby upGrad offline center to explore course options, get hands-on experience, and speak directly with mentors!

Unlock your potential with our free Software Development courses and start building essential skills for a successful tech career!

Boost your career with our popular Software Engineering courses, offering hands-on training and expert guidance to turn you into a skilled software developer.

Master in-demand Software Development skills like coding, system design, DevOps, and agile methodologies to excel in today’s competitive tech industry.

Stay informed with our widely-read Software Development articles, covering everything from coding techniques to the latest advancements in software engineering.

References:
https://www.tech-channels.com/techchannels-blog-news/java-turns-30-with-enhanced-data-handling-capabilities    
https://codedecodeacademy.com/understanding-java-23-features-in-2025-a-comprehensive-guide/    
https://bulldogjob.com/readme/every-new-feature-in-java-24

Frequently Asked Questions (FAQs)

1. Can I use primitive data types as objects in Java?

2. How does Java handle memory allocation for primitive and non-primitive types?

3. What happens if I assign a value outside the range of a primitive data type in Java?

4. Can non-primitive types be null in Java, and how does that affect my code?

5. How do I handle large decimal numbers in Java if I need more precision than a double?

6. What are the key advantages of using short over int in Java?

7. Is it possible to perform arithmetic operations on String data types in Java?

8. Can I change the value of a primitive data type once it is assigned in Java?

9. Why is char in Java a 16-bit data type?

10. What’s the default value of a primitive data type in Java?

11. How does typecasting work when converting between int and long in Java?

Rohan Vats

408 articles published

Software Engineering Manager @ upGrad. Passionate about building large scale web apps with delightful experiences. In pursuit of transforming engineers into leaders.

Get Free Consultation

+91

By submitting, I accept the T&C and
Privacy Policy

India’s #1 Tech University

Executive PG Certification in AI-Powered Full Stack Development

77%

seats filled

View Program

Top Resources

Recommended Programs

upGrad

AWS | upGrad KnowledgeHut

AWS Certified Solutions Architect - Associate Training (SAA-C03)

69 Cloud Lab Simulations

Certification

32-Hr Training by Dustin Brimberry

upGrad

Microsoft | upGrad KnowledgeHut

Microsoft Azure Data Engineering Certification

Access Digital Learning Library

Certification

45 Hrs Live Expert-Led Training

upGrad

upGrad KnowledgeHut

Professional Certificate Program in UI/UX Design & Design Thinking

#1 Course for UI/UX Designers

Bootcamp

3 Months