C#中的Attribute和Java中的Annotation

在以前的博客中介紹過C#的Attribute(特性),簡單的說,特性主要就是利用反射技術,在運行期獲取關注類的相關標註信息,而後利用這些標註信息對關注的類進行處理,最近由於工做的緣由,須要看一下Java,Java和C#實際上是很是想象的兩種語言,其實語言不少都相像,都在互相學習麼,在Java中有註解這個名詞,其實就是C#中的Attribute,原理和C#同樣,利用反射技術獲取運行時類的信息。

若是想要了解註解所表示的意思,那麼必須提供一個可以解析這個註解的工具,這個應該不用作過多的解釋,今天抽空,看了網上的例子,而後本身寫了一個Java的實例,本身封裝了一個註解處理類,固然不通用,話不u盾偶說了,直接上代碼。相關的類都在下面

package com.liuyu.Annotation;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.annotation.*;


public class AnnotationUtil {
    public static void getFruitInfo(Class<?> clazz) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        
        String strFruitName=" 水果名稱:";
        String strFruitColor=" 水果顏色:";
        String strFruitProvicer="供應商信息:";
        
        Field[] fields = clazz.getDeclaredFields();
        
        for(Field field :fields){
            if(field.isAnnotationPresent(Fruite.class)){
                Fruite fruitName = (Fruite) field.getAnnotation(Fruite.class);
                strFruitName=strFruitName+fruitName.value();
                System.out.println(strFruitName);
            }
            else if(field.isAnnotationPresent(Fruite.class)){
                FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
                
          

                 Method md= getGetMethod(clazz, field.getName());
                 
                Object s=   md.invoke(clazz,fruitColor.fruitColor());
                
                System.out.println(s.toString());
                strFruitColor=strFruitColor+fruitColor.fruitColor().toString();
                System.out.println(strFruitColor);
            }
            else if(field.isAnnotationPresent(Provider.class)){
                Provider fruitProvider= (Provider) field.getAnnotation(Provider.class);
                
                
                  Method mdSet= getSetMethod(clazz, field.getName());
                  Method mdGet= getGetMethod(clazz, field.getName());
                  
                  Object sValue;
                
                try {
                      Object g=    clazz.newInstance();
                       mdSet.invoke(g,new Object[]{fruitProvider.id()+fruitProvider.name()+fruitProvider.address()});
                       
                     sValue=  mdGet.invoke(g, new Object[]{});
                    
                    
                     System.out.println(sValue.toString());
                } catch (InstantiationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                  
                 
                
                strFruitProvicer=" 供應商編號:"+fruitProvider.id()+" 供應商名稱:"+fruitProvider.name()+" 供應商地址:"+fruitProvider.address();
              
                
                System.out.println(strFruitProvicer);
            }
        }
        
 
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Method getGetMethod(Class objectClass, String fieldName) {

        StringBuffer sb = new StringBuffer();

        sb.append("get");

        sb.append(fieldName.substring(0, 1).toUpperCase());

        sb.append(fieldName.substring(1));

        try {

            return objectClass.getMethod(sb.toString());

        } catch (Exception e) {

        }

        return null;

    }
    @SuppressWarnings("rawtypes")
    public static Method getSetMethod( Class objectClass, String fieldName) {       
          
        try {       
      
            Class[] parameterTypes = new Class[1];       
      
            Field field = objectClass.getDeclaredField(fieldName);       
      
            parameterTypes[0] = field.getType();       
      
            StringBuffer sb = new StringBuffer();       
      
            sb.append("set");       
      
            sb.append(fieldName.substring(0, 1).toUpperCase());       
      
            sb.append(fieldName.substring(1));       
      
            @SuppressWarnings("unchecked")
            Method method = objectClass.getMethod(sb.toString(), parameterTypes);       
      
            return method;       
      
        } catch (Exception e) {       
      
            e.printStackTrace();       
      
        }       
      
        return null;       
      
    }       
    
    public static void invokeSet(Object o, String fieldName, Object value) {       
          
        Method method = getSetMethod(o.getClass(), fieldName);       
      
        try {       
      
            method.invoke(o, new Object[] { value });       
      
        } catch (Exception e) {       
      
            e.printStackTrace();       
      
        }       
      
    }       
      
           
      
    /**    
     
     * 執行get方法    
     
     *     
     
     * @param o執行對象    
     
     * @param fieldName屬性    
     
     */       
      
    public static Object invokeGet(Object o, String fieldName) {       
      
        Method method = getGetMethod(o.getClass(), fieldName);       
      
        try {       
      
            return method.invoke(o, new Object[0]);       
      
        } catch (Exception e) {       
      
            e.printStackTrace();       
      
        }       
      
        return null;       
      
    }  
    
}
 

 

package com.liuyu.Annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Provider {
    /**
     * 供應商編號
     * @return
     */
    public int id() default -1;
    
    /**
     * 供應商名稱
     * @return
     */
    public String name() default "";
    
    /**
     * 供應商地址
     * @return
     */
    public String address() default "";
}

 

 

package com.liuyu.Annotation;


import java.lang.annotation.*;




@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
  
     public enum Color{ BULE,RED,GREEN}

     Color fruitColor() default Color.GREEN;

 

package com.liuyu.main;




import com.liuyu.Annotation.*;
import com.liuyu.Annotation.FruitColor.Color;

import java.lang.annotation.*;




public class FruitTest {
    
    @Fruite("Apple")
    private String appleName;
    
    @FruitColor(fruitColor=Color.RED)
    private String appleColor;
    
    @Provider(id=1,name="陝西紅富士集團",address="陝西省西安市延安路89號紅富士大廈")
    private String appleProvider;
    
    public void setAppleColor(String appleColor) {
        this.appleColor = appleColor;
    }
    public String getAppleColor() {
        return appleColor;
    }
    
    public void setAppleName(String appleName) {
        this.appleName = appleName;
    }
    public String getAppleName() {
        return appleName;
    }
    
    public void setAppleProvider(String appleProvider) {
        this.appleProvider = appleProvider;
    }
    public String getAppleProvider() {
        return appleProvider;
    }
    
    public void displayName(){
        System.out.println("水果的名字是:蘋果");
    }
}
package com.liuyu.main;

import java.lang.reflect.InvocationTargetException;

import com.liuyu.Annotation.*;


public class maintest {
    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        AnnotationUtil.getFruitInfo(FruitTest.class);

    }

}

如下是C#的一個例子,網上來的。能夠和上面的比較下,很相似。java

下面的代碼定義了一個名字爲widebright的自定義的屬性,而後還有測試使用的例子,用到了「反射」了,其實我也接觸很少「反射」這個東西,就是個提供運行時獲取類結構等的支持的東西了,還能夠用來動態加載庫等,好像。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Reflection;
namespace WindowsFormsApplication1
{
    //這裏利用AttributeUsage 來設置咱們的自定義屬性的應用範圍,這裏定義的能夠用於類,結構和方法的聲明
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method,
       AllowMultiple = true)] // multiuse attribute
    class widebright : Attribute //從Attribute 繼承,寫一個自定義屬性
    {
        private string strname;
        public widebright(string name)
        {
            strname = name;
        }
        //添加一個容許外部訪問的屬性
        public string Name
        {
            get { return strname; }
            set { strname = Name; }
        }
    }
    //寫一個測試類
    [widebright("widebright")]
    class widebrightTestClass
    {
        private string name = "hahaa";
        [widebright("test1")]
        public void TestMethod()
        {
            System.Console.WriteLine("哈哈,第一個測試經過");
        }
        [widebright("test2")]
        public void TestMethod2(string parm)
        {
            System.Console.WriteLine("哈哈,第二個測試經過,傳過來的參數是:{0}", parm);
        }
        public void TestMethod3()
        {
            System.Console.WriteLine("哈哈,第三個測試,name的值爲{0}", this.name);
        }
    }
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            widebrightTestClass testClass = new widebrightTestClass();
            //在程序運行時,獲取本身添加進去的「自定義屬性」
            Type type = testClass.GetType();
            testClass.TestMethod3 ();
            //利用反射 運行時修改對象的私有屬性
            BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Instance);
            type.GetField ("name",flags ).SetValue (testClass,"widebright");
            //再次調用方法,應該能夠看到name私有屬性確實被修改爲widebright了
            testClass.TestMethod3 ();
            foreach (Attribute attr in   type.GetCustomAttributes(false)) 
            {
                if (attr.GetType() == typeof(widebright)) 
                {
                    System.Console.WriteLine("testClass 對象具備 widebrihgt這個自定義屬性");
                }
              
            }
            //測試 widebright」自定義屬性「時候存在,獲取type的全部方法
            foreach (MethodInfo mInfo in type.GetMethods()) 
            {
            
                 foreach (Attribute attr in 
                    Attribute.GetCustomAttributes(mInfo)) 
                {
                    // Check for the AnimalType attribute.
                    if (attr.GetType() == typeof(widebright))
                    {
                        Console.WriteLine(
                            " {0}方法有一個 名字爲{1} 的\"widebright\" 屬性.", 
                            mInfo.Name, ((widebright)attr).Name );
                           if (((widebright)attr).Name == "test2" )
                           {
                               //動態調用testClass對象的方法
                               mInfo.Invoke(testClass, new string [] {((widebright)attr).Name});
                           }
                            else 
                           {
                               //第一個方法沒有參數,因此傳個null給他
                               mInfo.Invoke (testClass, null); 
                           }
                    }else{
                          Console.WriteLine(
                            " {0}方法不具備\"widebright\" 屬性.", 
                            mInfo.Name );
                    
                    }
            
               }
        }
      }

    }

運行程序後將打印:
哈哈,第三個測試,name的值爲hahaa
哈哈,第三個測試,name的值爲widebright
testClass 對象具備 widebrihgt這個自定義屬性
TestMethod方法有一個 名字爲test1 的"widebright" 屬性.
哈哈,第一個測試經過
TestMethod2方法有一個 名字爲test2 的"widebright" 屬性.
哈哈,第二個測試經過,傳過來的參數是:test2
頗有意思用法,呵呵, widebright手記
相關文章
相關標籤/搜索