Java 注解与 C# 特性

一、元数据简介 元数据是指用来描述数据的数据。对编程语言来说,元数据可以为程序中元素添加额外的信息。这一功能可以被用于描述代码间关系,以及代码与其他资源的联系。 元数据可以被用于框架中。通过元数据可以实现在代码上对类的直接配置,避免编写如 xml 的配置文件。 Java 和 C# 都具有为程序中元素,如类、方法等等,添加元数据的方式。Java中称为注解,而C#中称为特性。注解和特性都通过反射获取,关于两者的获取方式,已经在前一篇文章中有所记述。本篇只讨论注解和特性的定义和使用。 二、Java注解 注解的定义 如果想要自定义注解,需要继承 Annotation 类。 public class MyAnnotation extends Annotation { } 同时还有另一种写法,由此可知注释本质上是接口 public @interface MyAnnotation2 { } 和接口一样,注解可以添加静态变量 我们可以为注解添加“参数”,比如 Spring 中的注解 @Profile(value = "dev")。我们为其设置了 value 属性。 但是注解本是接口,不可能有保存数据的能力,要如何设置注解的属性呢?实际上,注解的属性在编写 Annotation 时是一个方法。即 public @interface MyProfile { String value(); } 还可以为参数添加默认值 public @interface MyAnnotation3 { String value(); int number() default 8; // set default number } 注解经常和枚举一起使用。 public @interface MyAnnotation4 { enum SELECT_TYPE {TYPE_A, TYPE_B} SELECT_TYPE selectType() default TYPE_A; } 元注解 元注解是注解的元数据,也就是对注解的注解。元注解为注解设置额外的信息,如设置注解的作用对象等等。...

二月 20, 2023 · 1 分钟 · 196 字 · Wokron

Java 和 C# 中的反射机制

一、反射简介 反射是一种程序动态访问修改其状态或行为的机制。具体来说,反射提供了在程序运行时对代码进行操作的手段。 反射提高了程序的灵活性和扩展性,能使程序员通过字符串动态地实现程序的修改。它降低了代码间的耦合度,可以避免硬编码,实现代码的组件化。反射的这些特点在对灵活性和扩展性要求很高的框架上有巨大的作用。 当然,也需要注意到,反射通过字符串进行操作的方式是解释性的,这将导致性能的降低。 二、反射的原理 对于拥有虚拟机(或者类似的东西,虚拟机只是一个不正规的名词)的语言,都存在加载字节码(同样不正规的名词)到虚拟机的过程。在这个过程中,虚拟机获取了有关类的信息,包括继承关系、包含的字段和方法等等。对于java来说,局部变量放在栈中,类实例放在堆中,程序方法放在方法区中。 对不使用反射的一般情况来说,方法调用更加直接。调用时虚拟机将根据编译时即确定的方法地址进行跳转。而对于反射,则需要根据字符串查找对应的类或方法。这样查找而非硬编码的过程就会影响性能。 二、java中的反射 通过反射我们能获取java语言中的如下组成部分:包、类(和接口)、方法(一般/构造)、字段、注解。反射不能操作方法中的内容。 类是面向对象的基本单元,我们通过获取类来实现对程序的动态操作。 (1)类和包 “类” Class<?> 是一个用于表示类的类型。它有三种获取方式 ClassName.class // 类型名.class obj.getClass(); // 对象.getClass Class.forName(String className); // Class.forName("包含包路径的类型全称") 前两种较好理解,相当于获取一个类型,我们可以用这编写一个类似于 instanceof 的函数。 boolean typeof(Object obj, Class<?> cls) { return obj.getClass() == cls; } 当然这无法将子类也判断为真。值得注意的是这里我们直接使用了 == 而不是 equals。因为对于每一个类,Class只用一个实例。 但第三种才最为重要,它通过字符串获取了一个类型。这就为程序提供了灵活性。 获取了一个 Class 对象后,我们可以进一步获取其父类和实现的接口 Class<?> cls = Class.forName("somepackages.someClass"); Class<?> superCls = cls.getSuperclass(); Class<?>[] interfaces = cls.getInterfaces(); 值得注意的是获取接口方法返回的是一个 Class 数组。这说明对于虚拟机来说本没有类和接口之分。 调用 getPackage 可以获取包 Package p = cls.getPackage(); Package 类型保存了该包的一些信息,如名称、版本等等,不一一列举。...

二月 19, 2023 · 3 分钟 · 537 字 · Wokron