顯示具有 java 標籤的文章。 顯示所有文章
顯示具有 java 標籤的文章。 顯示所有文章

2016年1月14日 星期四

來個標註吧 - Java annotation

Annotation在java裡,是給編譯器看的,
作用是告訴編譯器去做什麼,或是不做什麼。

Annotation package:
import java.lang.annotation.*;
先來看看它的語法,通常長的像這樣:
@annotation
或是這樣:
@annotation(value)
@annotation(element=value)
Annotation可指定element的值,或是直接傳入值。
它可以針對java的任何元素,
例如package、class、function、member...等進行標註。
像是這樣子:
class smaple{
    @Override
    public function overrideFunc(){
    }
}
那麼Annotation到底有什麼用,
我們來看看內建的幾個annotation。

@Override

告訴編譯器這個方法要覆蓋父類的方法,
例如上面的例子就是。
使用Override可以確保程式一定會覆蓋,
而不是變成重載。

@SuppressWarnings

這是告訴編譯器不要發出警告。
下面這個程式碼,編譯器會發出falling through warning。
switch("b"){
    case "a": break;
    case "b": //falling through
    case "c": break;
}
如果加上@SuperssWarnings annotation就不會發出警告。
@SuppressWarnings
private fallingThroughFunc(char x){
    switch(x){
        case "a": break;
        case "b": //falling through
        case "c": break;
    }
}
常用的參數有這些:
all
finally
unchecked
serial
fallthrough
path
你可以在命令列下這個指令,查到全部的參數
javac -X

@Deprecated

這個是純粹用來說明的,
告知開發者這個元素不建議使用,
請使用新的元素。
@Deprecated
public void deprecatedFunc(){
}

meta annotation

meta annotation是註釋的註釋,
annotation for annotation,好繞口啊。

@Retention

它告訴編譯器這個annotation的存在時期。
下方的例子,是告訴編譯器Deprecated一直到runtime都存在,
表示程式執行期同樣可以存取到。
@Retention(value=RUNTIME)
@Deprecated

Retention的參數有這些:
import java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.RetentionPolicy.SOURCE;
import java.lang.annotation.RetentionPolicy.CLASS;

@Inherited

使用Inherited來註釋一個class,
那麼它的子class也會繼承這個註釋。

@Documented

製作javadoc時,
使用Documented註釋某個annotation,
那麼這個被註釋的annotation會包含在javadoc中。

@Target

Target指明這個annotation可用在哪些元素。
import java.lang.annotation.ElementType.*;

@Target(ElementType.METHOD)
public @interface TargetSample{}
表示TargetSample只能用在mehtod。
@Target可以有多個值,像是這樣。
import java.lang.annotation.ElementType.*;

@Target(value={ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
public @interface TargetSample{}

2016年1月5日 星期二

java的反射機制 Reflection API

Reflection簡單的說,當你在寫code的時候,
有時你並不知道要實體化哪一個class,
而是在執行階段才決定實體化哪個class,
這時候就可以使用Reflection API。

使用反射實體化class

方法一:
取得class,然後實體化它。
這時使用的是預設建構式。

Class<?> clazz=Class.forName(className);
Fo fo=(Fo)clazz.newInstance();

方法二:
如果class 沒有default constructor
或是有數個constructor,
而你想指定使用其中一個。

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

Class<?> clazz=Class.forName(className);
//使用參數型態為String的constructor
Constructor<?> constructor=clazz.getConstructor(String.class);
//實體化
Object obj=constructor.newInstance("hi");


操作class的Method
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;

//取得class
Class clazz=Class.forName("someClass");

//取得method,並且指定參數類型
Method method=clazz.getMethod("methodName",String.class,int.class);

//取方法的修飾詞
int modifier=method.getModifier();

//取方法返回值
Type type=method.getGenericReturnType();

//取方法參數類型
Class[] klasses=method.getparameterTypes();

//取得method
Method med=clazz.getMethod("getInstance",int.class);

//呼叫static method,得到回傳值
Object resObj=med.invoke(null);

//取得method
Method noStaticMethod=clazz.getMethod("noStaticMethod",int.class);

//呼叫method,傳入呼叫這個方法的物件及參數,得到回傳值
Object resObj=noStaticMethod.invoke(clazz.newInstance(),3);

2015年12月18日 星期五

Running jar with multiple libraries

(A) Using Eclipse to export jar with Manifest file

1 Save new manifest in Export jar's JAR Manifest Specification page

2 Edit saved manifest file
    add  Class-Path:  lib/a.jar lib/b.jar lib/c.jar ... one parameters for single jar

(B) Using .sh file

1 Add -Djava.ext.dirs option

java -Djava.ext.dirs=libfolder -jar test.jar

Return different value from one function

public enum ReturnDifferent {

IntegerType,DoubleType,StringType;

  @SuppressWarnings("unchecked")
    public T comeback(String value) {
        switch (this) {
            case IntegerType:
                return (T) Integer.valueOf(value);
            case DoubleType:
                return (T) Double.valueOf(value);
            default:
                return null;
        }
    }
}

Unit Test:
public class ReturnDifferentTest {
@Test
public void testReturnDiff()
{
  Assert.assertTrue(ReturnDifferent.IntegerType.comeback("1") instanceof Integer);
    Assert.assertTrue(ReturnDifferent.DoubleType.comeback("1") instanceof Double);
}
}

Java thread number

JVM 相關參數 -Xms, -Xmx, -Xss
Linux 系統相關

/proc/sys/kernel/pid_max,
/proc/sys/kernel/thread-max,
max_user_process(ulimit -u),
/proc/sys/vm/max_map_count。