Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Friday, September 21, 2012

My first visualization of math

Following code rotates a triangle:

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
 
class Renderer implements GLEventListener 
{
    private GLU glu = new GLU();
 
    float  i = 0;
    
    public void display(GLAutoDrawable gLDrawable) 
    {
        i += 0.05f;
        
        final GL2 gl = gLDrawable.getGL().getGL2();
        
        
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
        gl.glLoadIdentity();
        
        
        gl.glTranslatef(0f, 0.0f, -6.0f);
        
        
        double rotCos = Math.cos(i);
        double rotSine = Math.sin(i);
          
          
          
        gl.glBegin(GL2.GL_TRIANGLES);       

        {
            double pointX = 0;
            double pointY = 1.0f; 
            double pointZ = 0f;
            
            double pointNewX = pointX * rotCos + pointY * rotSine;
            double pointNewY = -(pointX * rotSine) + pointY * rotCos;
            double pointNewZ = 0;
            
                    
            gl.glVertex3d(pointNewX , pointNewY , pointNewZ);   
        }
        
 
        
        {
            double pointX = -1f;
            double pointY = -1f;
            double pointZ = 0f;
            
            double pointNewX = pointX * rotCos + pointY * rotSine;
            double pointNewY = -(pointX * rotSine) + pointY * rotCos;
            double pointNewZ = 0;
            
            gl.glVertex3d(pointNewX , pointNewY , pointNewZ);       
        }
       
        
        
        
        {
            double pointX = 1f;
            double pointY = -1f;
            double pointZ = 0f;
            
            double pointNewX = pointX * rotCos + pointY * rotSine;
            double pointNewY = -(pointX * rotSine) + pointY * rotCos;
            double pointNewZ = 0;
            
            gl.glVertex3d(pointNewX , pointNewY , pointNewZ);       
        }
       
        
        
        gl.glEnd();
        
        

    }
 
 
    public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) 
    {
        System.out.println("displayChanged called");
    }
 
    public void init(GLAutoDrawable gLDrawable) 
    {
        System.out.println("init() called");
        GL2 gl = gLDrawable.getGL().getGL2();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glShadeModel(GL2.GL_FLAT);
    }
 
    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) 
    {
        
        System.out.println("reshape() called: x = "+x+", y = "+y+", width = "+width+", height = "+height);
        final GL2 gl = gLDrawable.getGL().getGL2();
 
        if (height <= 0) // avoid a divide by zero error!
        {
            height = 1;
        }
 
        final float h = (float) width / (float) height;
 
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, h, 1.0, 20.0);
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
 
 
    public void dispose(GLAutoDrawable arg0) 
    {
        System.out.println("dispose() called");
    }
}


Finally made sense of those bracketed expressions, thanks Wikipedia!

http://en.wikipedia.org/wiki/Rotation_(mathematics)

Monday, May 14, 2012

Java, moving furnitures around is a no-no. Refactoring-happy fellow be warned

class A { void m() { System.out.println("outer"); }}

public class TestInners {

 public static void main(String[] args) {
  new TestInners().go();
 }

 void go() {  
  new A().m();

  class A { void m() { System.out.println("inner"); } }  
 }

 class A { void m() { System.out.println("middle"); } }
}

You might have assumed the output is inner, since the class is in the same scope as the method. I don't know what are the Java language designers are thinking, it's more intuitive to choose the inner regardless of what line the class is declared. Java has some quirks on rules for resolving classes scope and accessibility, and this is one of those.

That code output is middle.


Move the class A at first line of go(), the output is inner:

void go() { 
 class A { void m() { System.out.println("inner"); } }  
 
 new A().m();
}

Monday, May 7, 2012

Java generic type erasure advantages and disadvantages

Java's type erasure on its generics allows the components produced on generics-using JVM be instantly available on non-generics JVM


An example, let's say we have a Greetable interface

interface Greetable<T> {
   String hello(T another);
}

On non-generics-capable Java, e.g. developers using JVM 1.4 or earlier, shall see Greetable's hello method's parameter as:



Type erasure has some problems though. Let's say you have two classes Geek and Hipster that implements the same interface, yet they can be friendly only among their own kind, this is where type erasure can be a problem. Read on.


class Hipster implements Greetable<Hipster>
{
    String _name;

    Hipster(String name) {
        _name = name;
    }

    @Override
    public String toString() {
        return _name;
    }

    @Override
    public String hello(Hipster another) {
        return "Hi I'm " + _name + ", hola mi amigo " + another + "!";
    }

}

class Geek implements  Greetable<Geek>
{
    String _name;

    Geek(String name) {
        _name = name;
    }

    @Override
    public String toString() {
        return _name;
    }

    @Override
    public String hello(Geek another) {
        return "Hi I'm " + _name + ", charie " + another + "!";
    }
}

You can see that both of them implements method hello, yet their accepted parameter is confined only to their own kind. This is where generics shine, error(type mismatches) can be caught during compile-time, not when it is costly to fix an error(during runtime)

Given this:

Hipster george = new Hipster("George");
Geek paul = new Geek("Paul");


Then you do this:
george.hello(paul); // compile error

That will not be allowed by the compiler, that will result to compile-time error. You use generics if you want to enforce types compatibility. Compiler can catch this error

// this is allowed. Hipster is derived from Greetable
Greetable<hipster> george = new Hipster("Pete"); 


Geek paul = new Geek("Paul");


// but this will not be allowed.
george.hello(paul); 


george.hello method signature is hello(Hipster another);. Paul is not a Hipster, he's a Geek, hence the compiler can catch that Paul doesn't matched George's friend preference of Hipster.


With type erasure, type mismatches are not caught by the compiler:


// this is allowed. Hipster is derived from Greetable
Greetable george = new Hipster("George"); 

george.hello(paul); // this will be allowed by the compiler. yet this will throw an exception during runtime

With type erasure, the type on george's hello method became an untyped one, it has method signature of hello(Object another). This has the consequence of the compiler not being able to catch type mismatches for you, hence the type incompatibility just arises during runtime only, the runtime will throw an exception; which is bad, it's better to fix errors earlier.

Sunday, April 8, 2012

Java and C# varargs difference need a mindset shift

Whereas in C#, this will output integer:

using System;
public class Test
{
        public static void Main()
        {
                int a = 7;
                DoStuff(a);
        }
        
        static void DoStuff(object x)
        {       
                Console.WriteLine("object");
        }
        
        static void DoStuff(params int[] x)
        {
                Console.WriteLine("integer");
        }
}

In Java, this will output object:

public class Main
{
        public static void main(String[] args)
        {
                int a = 7;
                DoStuff(a);
        }
        
        static void DoStuff(Object x)
        {
                System.out.println("object");
        }
        
        static void DoStuff(int... x)
        {
                System.out.println("integer");
        }
}

Thursday, April 5, 2012

int and short compatibility problem, not a versioning problem. it's a bad design decision

On my last post about int compatibility problem, I have an impression that the problem lies in the versioning problem.

On C# and C++, following would compile, but not in Java:

class Alien
{
 String invade(short ships) { return "int"; }
}


public class Invader
{
 public static void main(String[] args)
 {
  System.out.println(new Alien().invade(7));
 }
}


If it really is about versioning problem, why Java allows mapping numbers to float?


Java would compile this:

class Alien
{
        String invade(float ships) { return "float"; }
}

public class Invader
{
        public static void main(String[] args)
        {
                System.out.println(new Alien().invade(7));
        }
}

Now if you put Alien class and Invader class to their own file, the mappability of number to float shall have a versioning problem:

Alien.java:
class Alien
{
 String invade(float ships) { return "float"; }
}

Invader.java:
public class Invader
{
    public static void main(String[] args)
    {
        System.out.println(new Alien().invade(7));
    }
}

Compile both files, then run it, output will be:
float

Now try to modify the Alien.java and then re-compile it (note: don't re-compile Invade.java):

class Alien
{
 String invade(float ships) { return "float"; }
 String invade(int ships) { return "int"; }
}

Then re-run Invader (don't recompile it), output will be:
float

Now that's weird, if you read Invade.java source code, you can see that the number 7 could be mapped to overloaded method with int parameter, but since the burned instruction on the call site is bound to call the method with float parameter, the code would still continue to call the method with float parameter, regardless of the component(Alient.class) having a more compatible method, one that accepts int. To coerce the caller(Invader.class) to sync to the more fitting overloaded method, re-compile the Invader class. Then the output will be:

int


Seeing that a number is compatible to a method that accepts float, why not make it compatible to short then too?

Wednesday, June 8, 2011

Java Jar in 11 easy-to-follow steps

$ mkdir -p FirstProject/source/com/anicehumble
$ cd FirstProject/source/
$ vim com/anicehumble/Person.java

Then enter this:
package com.anicehumble;

public class Person {
        public static void main(String[] args) {
                System.out.println("Hello World");
        }
}

$ mkdir ../classes
$ javac -d ../classes com/anicehumble/Person.java 

The javac -d will build your Person.java in a mirror path(package) of your source code's path. So if you put your source code under the path of com/anicehumble, the -d ../classes parameter tells the compiler to put your compiled code in com/anicehumble path too, and under the classes path.

$ cd ../classes/

To test if your program is running properly(note, should use dots, not forward-slash, nor back-slash):
$ java com.anicehumble.Person

To put your class file in a JAR, create a manifest file first, indicating which class should the java runtime will look for main method:

$ echo "Main-Class: com.anicehumble.Person" > manifest.txt

Then put the classes in the jar, along with the manifest file:
$ jar -cvmf manifest.txt FTW.jar com/anicehumble/Person.class

Alternatively, you can do this, jar recursively get all the files if you just specify directory:
$ jar -cvmf manifest.txt FTW.jar com

To run:
$ java -jar FTW.jar

To make sure that your jar file is indeed self-contained:
$ mv FTW.jar ~/Desktop/
$ cd ../..
mv FirstProject x_Project 

The last step(mv, Unix's rename) above is to make sure that there's no false positive ;-)
$ cd ~/Desktop/

To run:
java -jar FTW.jar

Monday, June 6, 2011

Hello World

Michael-Buens-MacBook:src Michael$ mkdir -p a/nice/humble

Note above, if you are in Windows, create each directory(i.e. a, nice, humble) one by one.

Then create the file:

Michael-Buens-MacBook:src Michael$ vim a/nice/humble/Person.java

If you are in Windows, use Notepad++, it's an awesome editor.

Then type this:
package a.nice.humble;

public class Person {

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

Then type this in commandline:
Michael-Buens-MacBook:src Michael$ javac a/nice/humble/Person.java

Then type this in commandline to run your first program:
Michael-Buens-MacBook:src Michael$ java a.nice.humble.Person

Note, need to use dots, not forward-slash nor backward-slash

Output:
Hello World!

Saturday, June 4, 2011

Java

package buen.michael;

public class HelloWorld {
   public static void main(String[] args) {
       System.out.println("Hello World. Test Syntax Highlighter");
   }
}

Sunday, March 20, 2011

Java Stripes video tutorial

This is my first Java vlog. This tutorial shows how to setup Stripes in just few minutes