2

JAVA 基础之常用注解

 2 years ago
source link: https://segmentfault.com/a/1190000040957885
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JAVA 基础之常用注解

发布于 今天 14:43
今天来讲讲JAVA种常用的几种注解,比较容易使用,也简单

@Override检查覆盖方法是否正确
@Deprecated将这个方法置为不推荐使用的方法
@SupperessWarnings将某种警告提示忽略掉,可以放在类前面讲将整个类的这种警告忽略,也可以放在方法头上,只忽略这个方法的警告

public class Doer {
    @Deprecated
    void doItThisWay(){ }
    void doItThisNewWay(){ }
}

@SuppressWarnings("deprecation")
public class MyWorker {
    @SuppressWarnings("deprecation")
    void doSomeWork(){
        Doer d = new Doer();
        d.doItThisWay();
    }
    @SuppressWarnings("deprecation")
    void doDoubleWork(){
        Doer d1 = new Doer();
        Doer d2 = new Doer();
        d1.doItThisWay();
        d2.doItThisWay();
    }
}

自定义注解,通过@interface的方式定义,通过@新注解名字来使用注解
其中Target指定该新定义的注解可以使用在哪个地方@Target(ElementType.TYPE),@Target({ElementType.TYPE,ElementType.METHOD})等表示
另外Retention表示可以在何时可以获取到该新注解,RUNTIME表示在运行时可以获取到(想要通过反射获取到必须使用这种RUNTIME)
定义的变量可以设置为default值

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WorkHandler {
    boolean useThreadPool() default true;
}

使用新注解,当上面的定义default时true时候,下面如果是(useThreadPool = true)则可以去掉,除非设置为false必填写
这样通过注解可以判断是否使用线程池

@WorkHandler(useThreadPool = true)
public class AccountWorker implements Runnable, TaskWorker {
    BankAccount ba;
    public void setTarget(Object target) {
        if(BankAccount.class.isInstance(target))
            ba = (BankAccount) target;
        else
            System.out.println("Not BankAccount");
    }
    public void doWork(){
        Thread t = new Thread(HighVolumeAccount.class.isInstance(ba) ? (HighVolumeAccount)ba: this);
        t.start();
    }

    @Override
    public void run() {
        char txType = 'w';
        int amt = 200;
        if(txType =='w')
            ba.withdrawal(amt);
        else
            ba.deposit(amt);
    }
}

执行方法:

com.example.demo.pluralsight.runtimetype.BankAccount acct2 = new com.example.demo.pluralsight.runtimetype.BankAccount("2");
startWork("com.example.demo.pluralsight.metadatawithannotations.AccountWorker",acct2);
Thread.sleep(100);
System.out.println("TaskAccountWorker:"+acct2.getBalance());

private static void startWork(String workerTypeName, Object workerTarget){
    try{
        Class<?> workerType = Class.forName(workerTypeName);
        AccountWorker worker= (AccountWorker)workerType.newInstance();
        worker.setTarget(workerTarget);
        ExecutorService pool = Executors.newFixedThreadPool(3);
        WorkHandler wh = workerType.getAnnotation(WorkHandler.class);
        if(wh == null)
            throw new Exception("WorkHandler is null");
        if(wh.useThreadPool())
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    worker.doWork();
                }
            });
        else
            worker.doWork();
        pool.shutdown();
    }catch (Exception e){
        e.printStackTrace();
    }
}

还可以简写,直接定义新注解的变量名称为value,这样在类的前面写入的注解就可以直接写成@WorkHandler(false)

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WorkHandler {
    boolean value() default true;
}

自定义注解的变量类型可以为,Primitive type,String,Enum,Annotation,Class<?>,同时也可以是这些类型的数组。
传入class的方式,这样又可以节省一个传入参数

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ProcessedBy {
    Class<?> value();
}

@ProcessedBy(AccountWorkerProcessBy.class)
public class BankAccount {
    private String id;
    private int balance = 0;
    public BankAccount(String id){
        this.id = id;
    }
    public BankAccount(String id,int startBalance){
        this.id = id;
        balance = startBalance;
    }
    public String getId(){
        return id;
    }
    public synchronized int getBalance(){
        return balance;
    }
    public synchronized void deposit(int amount){
        balance += amount;
    }
    public synchronized void withdrawal(int amount){
        balance -= amount;
    }
}

public class AccountWorkerProcessBy implements Runnable {
    BankAccount ba;
    public void setTarget(Object target) {
        if(BankAccount.class.isInstance(target))
            ba = (BankAccount) target;
        else
            System.out.println("Not BankAccount");
    }
    public void doWork(){
        Thread t = new Thread(this);
        t.start();
    }

    @Override
    public void run() {
        char txType = 'w';
        int amt = 200;
        if(txType =='w')
            ba.withdrawal(amt);
        else
            ba.deposit(amt);
    }
}

执行方法:

BankAccount acct3 = new BankAccount("3");
startWorkSelfContained(acct3);
System.out.println("startWorkSelfContained:"+acct3.getBalance());

private static void startWorkSelfContained(Object workerTarget) throws Exception{
    Class<?> targetType = workerTarget.getClass();
    ProcessedBy pb = targetType.getAnnotation(ProcessedBy.class);
    Class<?> workerType = pb.value();
    AccountWorkerProcessBy worker = (AccountWorkerProcessBy) workerType.newInstance();
    worker.setTarget(workerTarget);
    worker.doWork();
}
输出
startWorkSelfContained:-200

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK