Java Datatypes
1. Basic Java types
Primitive Types: These are the fundamental building blocks of data. They are not objects and are stored directly as values.
Reference Types: Everything else in Java is an object.
- Primitive Types
- boolean: Represents a true or false value. Often used for flags, toggles, and conditional logic (e.g., isEnabled, isLoggedIn).
- byte: An 8-bit signed integer. Used for raw binary data, such as image data or network packets.
- short: A 16-bit signed integer. Less common, but can be used for memory optimization when dealing with large arrays.
- int: A 32-bit signed integer. Very common for representing counts, IDs, and other integer values.
- long: A 64-bit signed integer. Used for larger integer values, timestamps, and unique IDs.
- float: A 32-bit floating-point number. Used for representing decimal values, such as coordinates, sizes, and percentages.
- double: A 64-bit floating-point number. Used for higher precision decimal values.
- char: A 16-bit Unicode character. Used for representing single characters, such as letters or symbols.
- Reference Types
- String: Represents a sequence of characters. Very common for representing text, such as labels, user input, and data from APIs.
- Integer: A wrapper class for int. Used when you need to treat an int as an object (e.g., when using generics).
- Long: A wrapper class for long. Used when you need to treat a long as an object.
- Float: A wrapper class for float. Used when you need to treat a float as an object.
- Double: A wrapper class for double. Used when you need to treat a double as an object.
- Character: A wrapper class for char. Used when you need to treat a char as an object.
- Collections
- List: Represents an ordered collection of objects. Used for storing lists of data, such as contacts, messages, or items in a RecyclerView.
- Map: Represents a collection of key-value pairs. Used for storing data in a key-value format, such as user preferences or configuration settings.
- Set: Represents an unordered collection of unique objects. Used for storing unique data, such as a list of selected items.
- Object: The root class of all objects in Java. Used when you need to treat an object as an object.
- Arrays: Represents an array of objects. Used for storing data in an array format.
- ArrayList: Represents an array of objects. Used for storing data in an array format.
- HashMap: Represents a collection of key-value pairs. Used for storing data in a key-value format.
- HashSet: Represents an unordered collection of unique objects. Used for storing unique data.
- TreeMap: Represents an ordered collection of key-value pairs. Used for storing data in a key-value format.
- TreeSet: Represents an ordered collection of unique objects. Used for storing unique data.
- LinkedList: Represents a linked list of objects. Used for storing data in a linked list format.
- Type System:
- Static Typing: Java is statically typed. This means that the type of a variable is known at compile time.
- Strong Typing: Java is strongly typed. This means that the type of a variable cannot be changed.
- Type Checking: Java performs type checking at compile time. This means that the compiler will check the type of a variable before the code is executed.
- Type Inference: Java does not support type inference. This means that the type of a variable must be explicitly specified.
- Type Conversion: Java supports type conversion. This means that the type of a variable can be changed.
- Type Casting: Java supports type casting. This means that the type of a variable can be changed.
- Implicit Casting (Widening): When you cast a smaller type to a larger type (e.g., int to long), it's done automatically.
- Explicit Casting (Narrowing): When you cast a larger type to a smaller type (e.g., long to int), you need to do it explicitly using a cast operator.
- Autoboxing/Unboxing: Java automatically converts between primitive types and their corresponding wrapper classes (e.g., `int` to `Integer`, `double` to `Double`). This is called autoboxing. The reverse process, converting from a wrapper class to a primitive type, is called unboxing
- String Immutability: `String` objects in Java are immutable. Once a `String` object is created, its value cannot be changed. Any operation that appears to modify a `String` actually creates a new `String` object.
1: int myInt = 10;
2: long myLong = myInt; // Implicit casting (widening)
3:
4: long anotherLong = 100L;
5: int anotherInt = (int) anotherLong; // Explicit casting (narrowing)
1: Integer myInteger = 10; // Autoboxing (int to Integer)
2: int myInt = myInteger; // Unboxing (Integer to int)
1: String str1 = "Hello";
2: String str2 = str1 + " World"; // A new String object is created
2. Compare with C#
- Primitive Types: C# has a set of built-in primitive types, similar to Java:
- bool: true or false
- byte: 8-bit unsigned integer
- sbyte: 8-bit signed integer
- short: 16-bit signed integer
- int: 32-bit signed integer
- long: 64-bit signed integer
- float: 32-bit floating-point
- double: 64-bit floating-point
- char: 16-bit Unicode character
- string: Represents a sequence of characters.
- decimal: 128-bit decimal floating-point
- Reference Types (Objects): C# also has reference types, which are objects.
- string (a reference type, even though it's a primitive type)
- object (the base class for all other classes)
- User-defined classes
- Type System:
- Static Typing: C# is statically typed, like Java.
- Strong Typing: C# is strongly typed, like Java.
- Type Checking: C# performs type checking at compile time.
- Type Inference: C# supports type inference with the var keyword.
- Type Conversion: C# supports type conversion.
- Type Casting: C# supports type casting.
- Type Inference (var): C# allows you to use the var keyword to let the compiler infer the type of a variable.
- Value Types vs. Reference Types: C# has a distinction between value types (like int, struct) and reference types (like string, classes). Value types are stored directly on the stack, while reference types are stored on the heap. Value types are copied by value, while reference types are copied by reference.
- Structs: C# has struct types, which are value types that can have methods and fields. Structs are useful for creating small, lightweight objects.
- Nullable Types: C# has a special type called a nullable type. This is a type that can be null.
- String Immutability: C# string objects are immutable, like in Java.
- Type Conversion: C# has both implicit and explicit type conversion, similar to Java.
- Boxing and Unboxing: C# has boxing and unboxing, similar to Java.
- String Interpolation: C# has a feature called string interpolation, which allows you to embed variables directly into a string.
- enum Types: C# has enum types, which are used to create a set of named constants.
- delegate Types: C# has delegate types, which are used to create function pointers. C# has the event keyword, which is used to create events.
- dynamic Keyword: C# has the dynamic keyword, which allows you to create variables whose type is not known at compile time.
- object Type: The object type is the base class for all other types in C#.
- Checked and Unchecked Contexts: C# allows you to specify whether integer overflow should be checked or unchecked. Checked: In a checked context, an exception is thrown if an overflow occurs. Unchecked: In an unchecked context, overflow is ignored.
1: var myString = "Hello"; // The compiler will infer that this is a string
1: // Value type
2: int myInt = 10;
3: int anotherInt = myInt; // Copied by value
4:
5: // Reference type
6: string myString = "Hello";
7: string anotherString = myString; // Copied by reference
1: public struct MyStruct {
2: public int MyProperty { get; set; }
3: public void MyMethod() {
4: // ...
5: }
6: }
1: int? myNullableInt = null; // This is a nullable int
1: string str1 = "Hello";
2: string str2 = str1 + " World"; // A new string object is created
1: int myInt = 10;
2: long myLong = myInt; // Implicit conversion
3:
4: long anotherLong = 100;
5: int anotherInt = (int)anotherLong; // Explicit conversion
1: int myInt = 10;
2: objectmyObject = myInt; // Boxing (int to object)
3: int anotherInt = (int)myObject; // Unboxing (object to int)
1: string name = "John";
2: string greeting = $"Hello, {name}!"; // String interpolation
1: public enum Color
2: {
3: Red,
4: Green,
5: Blue
6: }
1: public delegate void MyDelegate(string message);
2: public event EventHandler MyEvent;
1: dynamic myDynamicVariable = "Hello";
1: object myObject = "Hello";
1: // Checked context
2: {
3: int maxInt = int.MaxValue;
4: int overflow = maxInt + 1; // This will throw an exception
5: }
6:
7: // Unchecked context
8: {
9: int maxInt = int.MaxValue;
10: int overflow = maxInt +1; // This will wrap around to int.MinValue
11: }
3. Automatic Implicit Conversions in C#
C# automatically performs implicit conversions when the compiler can guarantee that the conversion will not result in data loss or an exception. These conversions are considered safe and do not require explicit casting.
Here are some common scenarios where C# implements automatic implicit conversions:
- Widening Conversions:
- Converting a smaller data type to a larger data type (e.g., int to long, float to double).
- This is safe because the larger type can accommodate the full range of values of the smaller type.
- Numeric Type Conversions:
- Converting between certain numeric types where the conversion is considered safe (e.g., int to double, short to int).
- This is typically allowed when the target type has a larger range or higher precision than the source type.
- Reference Type Conversions:
- Converting from a derived class to a base class.
- This is safe because a derived class inherits all the members of its base class.
- Nullable Type Conversions:
- Converting a non-nullable value type to a nullable version of the same type (e.g., int to int?).
- This is safe because the nullable type can represent the full range of values of the non-nullable type, plus the null value.
- User-Defined Implicit Conversions:
- You can define custom implicit conversion operators for your own types to control how they are implicitly converted to other types.
- This allows you to create seamless conversions between your types without requiring explicit casting.
In this example, myInt is implicitly converted to a long without requiring an explicit cast. This is safe because a long can store the full range of values of an int.
1: int myInt = 10;
2: long myLong = myInt; // Implicit conversion from int to long
4. Automatic Implicit Conversions in Java
Similar to C#, Java also performs implicit conversions, also known as widening conversions
- Primitive Types:
- Widening Numeric Conversions: Converting a smaller numeric data type to a larger one, such as byte to short, int to long, float to double. This ensures that the value can be accommodated without truncation or loss.
- Character to Integer: Converting a char to an int, as each character has a corresponding Unicode value represented as an integer.
- Constant Expressions: If a constant expression's value fits within the range of a smaller data type, it can be implicitly converted to that type during assignment.
- Reference Types:
- Upcasting: Converting a subclass object to a superclass reference. This is safe due to inheritance, as the subclass object possesses all the properties and methods of its superclass.
1: int myInt = 10;
2: long myLong = myInt; // Implicit conversion from int to long
3:
4: byte myByte = 5;
5: int myInt2 = myByte; // Implicit conversion from byte to int
6:
7: char myChar = 'A';
8: int myInt3 = myChar; // Implicit conversion from char to int
9:
10: Dog myDog = new Dog();
11: Animal myAnimal = myDog; // Implicit conversion (upcasting) from Dog to Animal
Important Considerations about automatic conversion:
- Data Loss: While implicit conversions are generally safe, be mindful of potential data loss when converting between types with different ranges or precisions.
- Unexpected Behavior: In some cases, implicit conversions might lead to unexpected behavior if not carefully considered. Always understand the implications of implicit conversions in your code.
- User-Defined Conversions: When defining custom implicit conversions, ensure they are truly safe and do not introduce unexpected side effects.
Java context:
)
|
|