Wednesday 25 January 2012

Abstract Classes Have Constructors in decompiled code

1) In Java , we have default constructors provided for classes by the compiler (in case one is not declared).

2) The abstract classes can't be instantiated by using the new operator because they don't provide full implementation of all the methods.

Then does it make sense to have constructors inside abstract classes. Let us find it using a sample abstract class:
public abstract class Test{
   public abstract void doSomething();
}

The decompiled code for this class will show the truth about constructors in abstract classes in Java
public abstract class Test
{
    public Test()
    {
    }
    public abstract void doSomething();
}


Why?

The reason is that when a class extends any other class and an instance of the subclass is created then the constructor calls are chained and the super class constructors are invoked. This rule is no exception for abstract class

Moreover, having constructors in a class doesn't necessarily mean that instance of that class will be created using the new operator, but the constructors are intended for writing any initializing code.

Saturday 21 January 2012

Java Puzzler - double chars

The following compiles and produces an output. Can you explain why?

char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'

Here is a hint for a simpler example.

byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40

Checking the oddity of a integer number in java

From Jashua Bloch's "Java Puzzlers" book.

// Wrong way to check the oddity
public boolean isOdd(int num){
return (num % 2 == 1) // Broken- for all -ve odd numbers
}

The reason for this would be clear once you read about modulus operator.

// Right Solution
public boolean isOdd(int num){
return (num % 2 != 0)
}

// Much better and Faster
public boolean isOdd(int num){
return (num & 1)
}

Java puzzler: Initiating array of integer to object reference

Can you tell whether the following code will compile or not?

Object o = new int[10];

The answer to this is yes....because Arrays are object only....and super class of an array is java.lang.Object class.

Wednesday 18 January 2012

Java try-catch-finally and return simply


Consider this code :

boolean test () {
try {
return true;
}
finally {
return false;
}
}

Can you guess what will be returned?
This will always return false. My question: why is this? Is there a particular philosophy behind this design decision made by Java? I appreciate any insight, thank you.

Edit: I'm particularly interested as to 'why' Java thinks it's ok to violate the semantics that I define. If I 'return' in a try block, the method should return right then and there. But the JVM decides to ignore my instruction and return from a subroutine that actually hasn't yet been reached.

Technically speaking, the return in the try block won't be ignored if a finally block is defined, only if that finally block also includes a return.

It's a dubious design decision that was probably a mistake in retrospect (much like references being nullable/mutable by default, and, according to some, checked exceptions). In many ways this behaviour is exactly consistent with the colloquial understanding of what finally means - "no matter what happens beforehand in the try block, always run this code." Hence if you return true from a finally block, the overall effect must always to be to return true, no?

In general, this is seldom a good idiom, and you should use finally blocks liberally for cleaning up/closing resources but rarely if ever return a value from them.


Tuesday 17 January 2012

Concatenating integers in java

Suppose we have following values:

int a=1; 
int b=0;
int c=2;
int d=2;
int e=1;


If we want to concatenate these we can use 2 approaches:

Approach 1 : Using usual mathematics
int result = a * 10000 + b * 1000 + c * 100 + d * 10 + e;
String s = Integer.toString(result);

Approach 2 : Appending using StringBuilder
StringBuffer sb = new StringBuffer();
sb.append(a).append(b).append(c)...

Concatenating chars using + operator

Lets look at the following code snippet:
char c1 = 'A';
char c2 = 'B';

Lets try + operator first:

System.out.print(c1+c2);

Can you guess the output....it is not 'ab' but it 131 (= 65+66) i.e. sum of ascii value of 'A' and 'B'.

So it is not parallel to concatenating strings, but how should we concatenate 2 char's ?

Solution 1: Append using StringBuilder
StringBuilder sb = new StringBuilder('a').append('b').append('c');
System.out.println(sb.toString);

Solution 2 : Neater style using + operator for string concatenation
System.out.println("" + char1 + char2 + char3...);

Solution 3 : Using char array
System.out.println(new String(new char[]{a,b,c}));

Comparing the approaches
You should generally use second approach, third doesn't seem normal though and first approach looks like optimization flick. The approach selection depends on the char's having values at compile time or they are provided at the run time. So first read this article.

If the characters are constant, this is fine:
String s = "" + 'a' + 'b' + 'c';

If however they aren't, consider this:

String concat(char... chars) {
  if (chars.length == 0) {
    return "";
  }
  StringBuilder s = new StringBuilder(chars.length);
  for (char c : chars) {
    s.append(c);
  }
  return s.toString();
}

as an appropriate solution.

However some might be tempted to optimise:
String s = "Name: '" + name + "'"; // String name;
into this:
String s = new StringBuilder().append("Name: ").
append(name).append("'").toString();
While this is well-intentioned, the bottom line is DON'T.

Why? As another answer correctly pointed out: the compiler does this for you. So in doing it yourself, you're not allowing the compiler to optimise the code or not depending if its a good idea, the code is harder to read and its unnecessarily complicated.

For low-level optimisation the compiler is better at optimising code than you are.

Let the compiler do its job. In this case the worst case scenario is that the compiler implicitly changes your code to exactly what you wrote. Concatenating 2-3 Strings might be more efficient than constructing a StringBuilder so it might be better to leave it as is. The compiler knows whats best in this regard.

Caution for approach 3

System.out.println(new String(new char[]{a,b,c}));
Though String constructor provides method of concatenating char's, but + operator don't allow so....
So the output of this approach will be :

char alphabets =  {a,b,c};
System.out.println("Alfa "+alphabets);

Output expected may be Alfa abc but actually it is Alfa [C@16f0472.To get the above effect use following :
System.out.println(letters + " easy as " +String.valueOf(alphabets));

Expression evaluation can be compile time or runtime

Consider the expression:
String a = "a" + "b" + "c";
String b = System.getProperty("blah") + "b";

The first is evaluated at compile-time. The second is evaluated at run-time. So in case of strings,
never replace constant concatenations (of any type) with StringBuilder, StringBuffer or the like. Only use those where variables are invovled and generally only when you're appending a lot of operands or you're appending in a loop.

Assignment vs compound assignment operator

Assignment operator ( = ) and compound assignment operators (like +=, -=, etc) do the same thing in the end, ie. assignment. But there is slight difference between assignment and compound operator.

Case 1 : Operands are primitive types
In this case that it silently casts the operand on the right side to the operand on the left side. So consider the following statement:
short x = 0;
int i = 123456;

So this expression will work:
x+=i //works

This will not:
x = x + i ; //compile time error -  "possible loss of precision"

To avoid unpleasant surprises, do not use compound assignment operators on variables of type byte, short, or char.

Case 2 : Case of objects
Consider following code:
Object x = "Raj ";
String i = "has taj";

Again here the case is opposite:
x = x + i ; //works

This will not work, because += will work for string, if rhs argument is string.

x+=i //error - incompatible types...


Conditional Operator with different operand types

Lets have a look at this program:
char x = ’X’;
int i = 0;
System.out.print(true ? x : 0);
System.out.print(false ? i : x);

Expected output is XX, but output printed is X88....can you guess why??????

The reason for this is mixing 2 different types of operands...here char and int.

So lets first see, how conditional operator works in java, see JLS 15.25
The rules for determining the result type of a conditional expression are too long and complex to reproduce in their entirety, but here are three key points.
1. If the second and third operands have the same type, that is the type of the conditional expression. In other words, you can avoid the whole mess by steering clear of mixed-type computation.
2. If one of the operands is of type T where T is byte, short, or char and the other operand is a constant expression of type int whose value is representable in type T, the type of the conditional expression is T.
3. Otherwise, binary numeric promotion is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

So now lets see the first expression:

System.out.print(true ? x : 0);
Here first operand is char, and second operand is constant so 2nd point will apply...so type will remain T..i.e. char...so right output is printed.

Consider the second case:

System.out.print(false ? i : x);
Here first operand is integer variable and second operand is character, so argument 3 will hold....so char is promoted to int and ascii value of char is printed.

Making it print XX will only take to make i as final.
final int i = 0;


Why swap with xor works fine in c++ but in java doesn't ?

Look at the following java snippet:
int x=1;
int y=2;
x ^= y ^= x ^= y;

I am expecting the values to be swapped.But it gives x=0 and y=1. when i tried in C / CPP language it gives the correct result.

So what is the reason...lets look at it:
x = x ^ (y = y ^ (x = x ^ y));

Unlike in C, in Java the left operand of a binary operator is guaranteed to be evaluated before the right operand. Evaluation occurs as follows:
x = x ^ (y = y ^ (x = x ^ y))
x = 1 ^ (y = 2 ^ (x = 1 ^ 2))
x = 1 ^ (y = 2 ^ (x = 3))
x = 1 ^ (y = 2 ^ 3)             // x is set to 3 
x = 1 ^ (y = 1)
x = 1 ^ 1                       // y is set to 1
x = 0                           // x is set to 0

You could reverse the order of the arguments to each xor expression so that the assignment is done before the variable is evaluated again:
x = (y = (x = x ^ y) ^ y) ^ x
x = (y = (x = 1 ^ 2) ^ y) ^ x
x = (y = (x = 3) ^ y) ^ x 
x = (y = 3 ^ y) ^ x             // x is set to 3
x = (y = 3 ^ 2) ^ x
x = (y = 1) ^ x
x = 1 ^ x                       // y is set to 1
x = 1 ^ 3
x = 2                           // x is set to 2
This is a more compact version that also works:
x = (y ^= x ^= y) ^ x;

But this is a truly horrible way to swap two variables. It's a much better idea to use a temporary variable.
int t = a;
a = b;
b = t;

Also, the xor logic will work, if we have 3 separate statement
a ^= b; 
b ^= a;
a ^= b;


Monday 16 January 2012

Long division in java (for large numbers)

class LongDiv{
public static void main(String [] args){

    final long x = 24*60*60*1000*1000;
    final long y = 24*60*60*1000;
    System.out.println(x/y);
}
}


although the expected answer is 1000, but the javac gives it as 5. Reason?

Solution:
This happens because / is int operator, so large values while division are converted to integer and overflow happens. So to stop this "silent overflow" we have to use literal L to stop it.
final long x = 24L*60L*60L*1000L*1000L;
final long y = 24L*60L*60L*1000L;
System.out.println(x/y);



The x you computed, in the integer range, was 500654080. This divided by the y ( = 86400000), results in 5.794607407407407.... Java truncates the decimal part which causes the 5.

By adding an L after the number literal, you tell the compiler to compile it as a long instead of an int. The value for x you expected is 86400000000. But is was compiled as an int.

We can reproduce the wrong value for x (500654080) by truncating it to an int:
// First correct
long x = 24L*60L*60L*1000L*1000L;
/* x = `86400000000`; */
// Now truncate
x &= 0xFFFFFFFFL; // again: don't forget the L suffix
/* x = `500654080` */

Some languages don't do this, but support target typing, a language feature wherein the type of the variable in which a result is to be stored influences the type of the computation.