Tuesday, March 6, 2012

Assigning integer to character is perfectly allowable in Java, C/C++

char c = 65; // Java, C/C++ would allow this. C# won't
System.out.println(c); // outputs A



need to typecast in C#
char c = (char) 65;
Console.WriteLine(c);

Saturday, March 3, 2012

Java reference type primitives gotcha

Java has a gotcha on its reference type primitives, any reference type primitives that has a value between -128 to 127 are cached, in order to save memory. When you compare any number that fall on that range, don't be surprised that reference types with same values points to the same memory location

private static void firstTestRef() {                                   
 System.out.println("First Test Ref\n");                            
                                                                    
 Integer a = 126;                                                   
 Integer b = 127;                                                   
                                                                    
 System.out.printf("Same reference b == a : %b\n", b == a);         
 System.out.printf("Same value b.equals(a) : %b\n\n", b.equals(a)); 
                                                                    
 ++a;                                                               
 System.out.printf("Same reference b == a : %b\n", b == a);         
 System.out.printf("Same value b.equals(a) : %b\n\n", b.equals(a)); 
}                                                                      

Output:
First Test Ref

Same reference b == a : false
Same value b.equals(a) : false

Same reference b == a : true
Same value b.equals(a) : true


See the output above? When you increment a, the runtime will check first if the value is in -127 to 128 range, if it is, it will find an existing object with same value, and reference that object instead


Now check the output of this one, values that are not in -128 to 127 range:

private static void secondTestRef() {                                  
 System.out.println("Second Test Ref\n");                       
                                                                    
 Integer a = 128;                                                   
 Integer b = 129;                                                   
 Integer c = a;                                                     
                                                                    
                                                                    
 System.out.printf("Same reference a == c : %b\n", a == c);         
 System.out.printf("Same value a.equals(c) : %b\n\n", a.equals(c)); 
                                                                    
 System.out.printf("Same reference b == a : %b\n", b == a);         
 System.out.printf("Same value b.equals(a) : %b\n\n", b.equals(a)); 
                                                                    
 ++a;                                                               
 System.out.printf("Same reference b == a : %b\n", b == a);         
 System.out.printf("Same value b.equals(a) : %b\n\n", b.equals(a)); 
                                                                    
 --a;                                                               
 System.out.printf("Same reference a == c : %b\n", a == c);         
 System.out.printf("Same value a.equals(c) : %b\n\n", a.equals(c)); 
}   


Output:

Second Test Ref

Same reference a == c : true
Same value a.equals(c) : true

Same reference b == a : false
Same value b.equals(a) : false

Same reference b == a : false
Same value b.equals(a) : true

Same reference a == c : false
Same value a.equals(c) : true

When you increment a, even it will have same value as b, their referenced memory location will not be the same. Even if you assign a its old value, a will be a new object already; so, even a has same value as c, it will not reference c

Tuesday, February 28, 2012

Static initialization block

Static Initialization Block


package com.anicehumble;


public class MainClass {

 public static void main(String[] args) {  
 
  System.out.println("Hello");
  Great.test();
  Great.test();
      
 }
}

package com.anicehumble;

public class Great {

 static 
 {
  System.out.println("One Time");
 }
 
 public static void test()
 {
  System.out.println("Test");
 }
 
}

Output:
Hello
One Time
Test
Test


Friday, February 24, 2012

When in Rome do as Romans do

So if you are accustomed to C# importing all classes from a namespace with using keyword:

using System.Collections.Generic;

Don't be tempted to do the same in Java:

import java.util.*;

Import classes explicitly:

import java.util.List;
import java.util.ArrayList;





Thursday, February 9, 2012

Java access modifiers from a C# developer perspective

C#'s internal...

Great/TheRoot.cs:
namespace Great 
{
 // internal is the class' default access.
 // it's optional to explicitly state if the class is internal
 class TheRoot 
 {
  // private is the default access of a class member, 
  // it's a must to explicitly state if a member is internal
  internal void DoSomething() 
  {   
  }
 }
}



…to Java's internal:

great/TheRoot.java:
package great;

// internal is the class' default access,
// and there is no Java keyword to explicitly state so
class TheRoot
{
 // internal is the default access of a class member, 
 // and there is no Java keyword to explicitly state so
 void doSomething() 
 { 
 }
}



C#'s private member…

Great/TheRoot.cs:

namespace Great
{
 class TheRoot
 { 
  // private is the default access of a class' member, 
  // it's optional to explicitly state if a member is private  
  void DoSomething()
  {
  }
 }
}


…to Java's private member:

great/TheRoot.java:
package great;

class TheRoot
{
 // internal is the default access of a class' member,
 // so it's a must to explicitly state if a member is private
 private void doSomething() 
 {
 }
}



C#'s internal protected member...


Great/TheRoot.cs:
namespace Great
{
 class TheRoot
 {
  // private is the default access of a class' member.
  // internal makes a member accessible to a non-deriving class that are in the same assembly as the member
  internal protected void DoSomething()
  {
  }
 }
}

Great/MainClass.cs:
namespace Great
{
 // non-deriving class
 class MainClass
 {
  public static void Main(string[] args) 
  {
   TheRoot b = new TheRoot();

   // accessible if this class is compiled in the same assembly(i.e. all, exe) as TheRoot class.
   // not accessible when this MainClass is compiled in different assembly
   b.DoSomething(); 
  }
 }
}

Ball/MainClass.cs:
namespace Ball
{
 // non-deriving class
 class MainClass
 {
  public static void Main(string[] args)
  {
   Great.TheRoot b = new Great.TheRoot();
   
 
   // as long as this class is compiled in the same assembly as TheRoot class, 
   // even this class is in different namespace, the DoSomething method will still be accessible.   
   b.DoSomething(); 
  }
 }
}



…to Java's internal protected member:

great/TheRoot.java:
package great;

class TheRoot
{
 // internal is the default access of a class' member in java, adding protected keyword doesn't cancel it.
 // there's no Java keyword to explicitly state internal access
 protected void doSomething() 
 {
 }
}

great/MainClass.java:
package great;

// non-deriving class
class MainClass
{
 public static void main(String[] args) 
 {
  TheRoot b = new TheRoot();

  // accessible
  b.doSomething(); 
 }
}



ball/MainClass.java:
package ball;

// non-deriving class
class MainClass
{
 public static void main(String[] args) 
 {
  great.TheRoot b = new great.TheRoot();

  // not accessible anymore. this class reside in different package
  b.doSomething(); 
 }
}



C#'s protected member...

Great/TheRoot.cs:
namespace Great
{
 class TheRoot
 {
  // private is the default access of a class' member.
  // protected makes a member accessible to the deriving class only
  protected void DoSomething()
  {
  }
 }
}

Great/MainClass.cs:
namespace Great
{
 // non-deriving class
 class MainClass
 {
  public static void Main(string[] args) 
  {
   TheRoot b = new TheRoot();

   // not accessible. protection works. similar to C++
   b.DoSomething();  
  }
 }
}


…to Java's protected member:


great/TheRoot.java:
package great;

class TheRoot
{
 // internal is the default access of a class' member in Java, 
 // adding protected keyword doesn't cancel it.
 // there's no Java keyword to cancel internal access on a protected member
 protected void doSomething() 
 {
 }
}


great/MainClass.java:
package great;

// non-deriving class
class MainClass
{
 public static void main(String[] args) 
 {
  TheRoot b = new TheRoot();

  // accessible, protection doesn't work. Java is the odd one out, whereas C#'s protected is same as C++'s protected semantics
  b.doSomething(); 

  // Note: if doSomething is accessed outside of package, protection works as intended.
  // In this example, the accessing method is in the same package as the accessed method, 
  // protection doesn't work.
 }
}




Sunday, February 5, 2012

2D dock gives you more concentration

As rounded corners point inward and focus your eyes on the content inside an object, any UI objects that are rounded-shape grabs your attention better than those are not.




Rounded corners also point inward and focus your eyes on the content inside an object. A squared edge is the exact opposite – it focuses your eyes on the stuff outside of the object. When you look at the rectangular buttons of iOS 4, you have to work harder to shift your gaze from the outside to the inside of the button.




Now that explains my preference for 2D dock than the 3D dock. As most Mac applications has rounded icons, those apps on 3D dock can often grab your attention while you are doing some task. The 2D dock serves as a boundary between your main task and those rounded-shape app icons.

3D dock has the potential to grab your attention often, as those rounded-shape app icons don't have an object to cover them


2D dock has a boundary, while you are working on some task, it shields your eyes against those rounded-shape app icons.

Monday, January 30, 2012

Cannot find /Library/Tomcat/Home/bin/setclasspath.sh

When starting Tomcat on Lion:
$ /Library/Tomcat/bin/startup.sh 
And you encountered this error:
Cannot find /Library/Tomcat/Home/bin/setclasspath.sh This file is needed to run this program
just unset the CATALINA_HOME variable:
$ unset CATALINA_HOME

Then run this again:
/Library/Tomcat/bin/startup.sh 

Then visit http://127.0.0.1:8080

Troubleshooting idea got from this: http://www.malisphoto.com/tips/tomcatonosx.html


Another approach is to use sudo:

sudo /Library/Tomcat/bin/startup.sh 

Then visit http://127.0.0.1:8080