zoukankan      html  css  js  c++  java
  • 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#的一个例子,网上来的。可以和上面的比较下,很类似。

    下面的代码定义了一个名字为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手记
  • 相关阅读:
    菜鸟成长记(十二)----- 生活的意义是什么?
    菜鸟成长记(十一)----- 操蛋的2016与未知的2017
    菜鸟成长记(十)----- 好笑的格局
    菜鸟成长记(九)----- 当我作死的时候,我在想些什么。
    菜鸟成长记(八)----- 一个萝卜一个坑
    菜鸟成长记(七)----- 如何叫醒一个装睡的人?
    菜鸟成长记(六)----- 懒惰与惶恐的挣扎
    C++类的数组元素查找最大值问题
    成为IT精英,我奋斗了7年
    DS1337 时钟芯片在 C8051F 上的实现
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/3980608.html
Copyright © 2011-2022 走看看