01: Java data types interview Q&As

Q1. How would you go about choosing the right data types for your application?
A1. Java is what is known as a strongly typed language. This means Java only accepts specific values within specific variables or parameters. Some languages, such as JavaScript, PHP, and Perl are weakly typed languages.

1. Know the data limits to prevent any data overflow

Java primitive data types

Java primitive data types

2. Prefer immutable wrapper objects to primitives.

Each primitive data type has a corresponding wrapper class like Integer, Long, Character, Float, Double, etc. There are 8 primitive variables and as many wrapper objects. In Java 5, additional wrapper classes like AtomicInteger, AtomicLong, AtomicBoolean and AtomicReference were introduced to provide atomic operations for addition, increment, and assignment. These additional classes are mutable and cannot be used as a replacement for regular immutable wrapper classes.

Q2. What are wrapper classes, and why do you need them?
A2. The wrapper classes are a good example of the decorator design pattern. They decorate the primitive values, and enhance their behavior by providing immutability, atomicity, null checking, etc.

1) Wrapper objects can be initialized to null. This can’t be done with primitives. Many programmers initialize numbers to 0 or -1 to signify default values, but depending on the scenario, this may be incorrect or misleading.

2) Wrapper objects are very useful for optional data. Databases almost always have a significant fraction of their fields as optional (that is, as possibly NULL). In addition, the forms submitted in Web applications can contain optional parameters. Both NULL database fields and missing request parameters naturally map to null object references. With primitives, there is no such natural mapping.

3) Wrapper objects will also set the scene for a NullPointerException when something is being used incorrectly, which is much more programmer-friendly as it fails fast than some arbitrary exception buried down the line. Preferably, check for null early on in the method and report it immediately where applicable to adhere to the fail fast principle.

4) The wrapper objects are immutable, hence inherently thread-safe. Other threads can only read the values set by the thread that initialized this object.

5) When you create wrapper objects, use the valueOf( ) static factory method for efficiency.

The second approach is in fact an implementation of the flyweight design pattern.

Q. When to prefer primitives?
A. Primitives are faster to create and use than wrapper objects. Wrapper objects need to be auto-unboxed before use. Thus there is an extra step for the JVM to perform. For example, in order to perform arithmetic on an Integer, it must first be converted to an int before the arithmetic can be performed. In many business applications this rarely matters unless you were writing something very number-crunching or profiling indicates that the auto-boxing is a performance or memory issue in a particular part of your code as it is executed very frequently.

Anti-pattern: Watch out for premature-optimization anti-pattern where you are tempted to code for a perceived performance gain and sacrificing good design and maintainability.

Q3. When working with floating-point data types, what are some of the key considerations?
A3.

1. Never compare float or double with “==” or != operator

2. Use long, int, or BigDecimal for storing money, and performing monetary calculations.

Floating point data types like float, double, Float, or Double can result in inaccurate results. use either the BigDecimal or int/long representing the value in its lowest units like cents.

Q4. What is your understanding of widening versus narrowing conversions of primitive data types?
A4. Left to right (e.g. byte to short) is a widening conversion and considered safe because there is no chance for data loss. For example, byte has a range between -128 and 127 and short has a wider range between -32768 and 32767. So when you go from left to right, the data types are implicitly cast by the compiler since it is safe to do so.

Java primitive data types

Java primitive data types

Right to left (e.g. short to byte) is a narrowing conversion and considered unsafe because there is a chance for data loss. So when you go from right to left, the compiler expects you to explicitly cast the data to clearly state that it is safe to do so. If you do not cast explicitly, you will get a compile-time error. For example,

Note: byte and short are signed data types and they cannot be implicitly cast to unsigned char data type even though it is a widening conversion.

Q5. What are the dangers of explicit casting?
A5. Not knowing the MIN and MAX values can result in unexpected results due to loss of data during narrowing.

Trap #1 Be careful when casting explicitly.

Trap #2: Simple binary operations apply ‘binary numeric promotions’

The binary numeric promotion rule automatically casts each operand to the size of the larger operand type. If neither operand is larger, then both are cast to the same type. In byte b = b + 10, the value 10 is of type int and is the larger operand type compared to b, which is of type byte, hence will be evaluated as follows:

Above code throws a compile time error because b+10 evaluates to an int. You need an explicit cast to convert an int to byte as it is a narrowing conversion.

Trap #3: Compound Operators, such as +=, -=, etc contain an explicit cast

In byte b+=10 compound binary operation, you may be thinking that b+=10 will be expanded as b = b + 10. But it is really not correct. This is because the compound operations will have an explicit cast in the converted byte code.

performing a compound assignment operation (e.g. +=, -=, *=, etc). You may be thinking that b+=10 will be expanded as b = b + 10. But it is really not correct. This is because the compound operations will have an explicit cast even though it is not shown in the code.

Q6. Do you think the following code will throw a compile-time exception? If yes, how will you fix it?

A6. Yes. It is cast first and then divided as casting operator has precedence over division operator as per the precedence table. So the above code is equivalent to

To fix it, you need to get the division operator to evaluate prior to casting. You can achieve this by introducing a parenthesis around the division as parenthesis has higher precedence (in fact highest) than casting as per the precedence table.

Q7. What is the output of the following code snippet?

A7. x=6, y=7, z=6

line 1: x=5, y=0, z=0
line 2: x=6, y=6, z=0;
line 3: x=6, y=7, z=6

You need to understand the pre and post increment operators to get this right. ++x is a pre-increment and x++ is a post increment. ++x means x is incremented before being used and x++ means x is incremented after being used. So line2 increments x by one and then assign it to y. Whereas in line 3, z is assigned the old y value (i.e. prior to incrementing) of 6 and then y value is incremented to 7.

As you may rightly ask that as per the precedence table, both pre-increment (i.e. ++expr) and post-increment (i.e. expr++) operators do have precedence over the assignment operator (i.e “=”). The line 3 int z = y++; is roughly evaluated as follows:

Q8. Can you list some practical applications where the bitwise operations can be applied?
A8.

Example 1: To pack and unpack values.

For example, to represent

  • age of a person in the range of 0 to 127. Use 7 bits.
  • gender of a person 0 or 1 (0 – female and 1 – male). Use 1 bit.
  • height of a person in the range of 0 to 255. Use 8 bits.

To pack this info: (((age << 1) | gender ) << 8 ) | height. For example, age = 25, gender = 1, and height = 255cm. Shift the age by 1 bit, and combine it with gender, and then shift the age and gender by 8 bits and combine it with the height.

Bitwise operations

Bitwise operations

Output:

packed=13311
packed binary=11001111111111
height=255
gender=1
age=25

Screen shot 2014-10-01 at 6.15.38 PM

Example 2: To compactly represent a number of attributes like being bold, italics, etc of a character in a text editor.

This is a more practical example.

Screen shot 2014-10-01 at 6.16.59 PM

Example 3: If you can think of anything as slots or switches that need to be flagged on or off,

you can think of bitwise operators. For example, if you want to mark some events on a calendar.

Screen shot 2014-10-01 at 6.19.37 PM

Example 4: To multiply or divide by 2n


300+ Java Interview FAQs

Tutorials on Java & Big Data