vs 2008网站做安装包,专业做网站的公司哪家好,岳阳做网站公司,湖州网站seo优化下面是详细地讲解 Java 中的注解与反射#xff0c;并提供了很多的示例来帮助理解。
Java 注解#xff08;Annotations#xff09;
1. 注解的基本概念
注解#xff08;Annotation#xff09;是 Java 5 引入的一种用于为代码元素#xff08;类、方法、字段、参数等…下面是详细地讲解 Java 中的注解与反射并提供了很多的示例来帮助理解。
Java 注解Annotations
1. 注解的基本概念
注解Annotation是 Java 5 引入的一种用于为代码元素类、方法、字段、参数等添加元数据的机制。这些元数据可以在编译时、类加载时或运行时被读取并使用。注解不会直接影响代码的执行但可以通过工具或框架来处理这些元数据以实现一些功能。
2. 内置注解
Java 提供了一些常用的内置注解
Override用于标注方法表明该方法重写了父类的方法。Deprecated用于标注过时的元素编译器看到使用了这个元素会发出警告。SuppressWarnings用于抑制编译器警告。
public class AnnotationExample {Overridepublic String toString() {return AnnotationExample;}Deprecatedpublic void deprecatedMethod() {// 这个方法已经过时}SuppressWarnings(unchecked)public void suppressWarningsExample() {List rawList new ArrayList();rawList.add(example);}
}3. 自定义注解
你可以定义自己的注解并通过元注解meta-annotation来指定注解的行为。
元注解:
Retention指定注解的保留策略取值有 RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。Target指定注解可以应用的程序元素取值有 ElementType.TYPE、ElementType.FIELD、ElementType.METHOD、ElementType.PARAMETER 等。Documented指定注解是否包含在 Javadoc 中。Inherited指定注解是否可以被子类继承。
import java.lang.annotation.*;Retention(RetentionPolicy.RUNTIME) // 运行时保留
Target(ElementType.METHOD) // 作用于方法
public interface MyAnnotation {String value();
}public class MyClass {// 当 MyClass 的 myMethod 方法被注释了这个注解后可以通过反射在运行时获取这个注解及其值。下面的结合注解与反射有例子MyAnnotation(value example)public void myMethod() {System.out.println(Method with MyAnnotation);}
}Java 反射Reflection
1. 反射的基本概念
反射是一种运行时机制允许程序在运行时检查和操作类、方法、字段等。通过反射你可以
获取类的详细信息类名、修饰符、父类、接口等。获取类的方法、构造函数、字段等。动态调用方法或构造函数。动态访问和修改字段的值。
2. 获取类的信息
获取 Class 对象
有多种方法可以获取一个类的 Class 对象
Class.forName(String className): 通过类的完全限定名获取 Class 对象。
ClassName.class: 通过类的字面常量获取 Class 对象。
object.getClass(): 通过对象实例获取 Class 对象。
// 获取 Class 对象的三种方式
Class? clazz1 Class.forName(java.util.ArrayList);
Class? clazz2 ArrayList.class;
ArrayListString list new ArrayList();
Class? clazz3 list.getClass();3. 获取类的成员
getDeclaredFields() 获取类的所有字段包括私有字段。
getDeclaredMethods() 获取类的所有方法包括私有方法。
getDeclaredConstructors() 获取类的所有构造函数。
getField(String name) 获取类的指定字段不包括私有字段。
getMethod(String name, Class?... parameterTypes) 获取类的指定方法不包括私有方法。
getConstructor(Class?... parameterTypes) 获取类的指定构造函数。
Class? clazz Class.forName(java.util.ArrayList);// 获取所有声明的字段
Field[] fields clazz.getDeclaredFields();
for (Field field : fields) {System.out.println(字段: field.getName());
}// 获取所有声明的方法
Method[] methods clazz.getDeclaredMethods();
for (Method method : methods) {System.out.println(方法: method.getName());
}// 获取所有声明的构造函数
Constructor?[] constructors clazz.getDeclaredConstructors();
for (Constructor? constructor : constructors) {System.out.println(构造函数: constructor.getName());
}4. 动态创建对象
newInstance() 使用无参构造函数创建对象。
Constructor.newInstance(Object... initargs) 使用指定构造函数创建对象。
Class? clazz Class.forName(java.util.ArrayList);// 使用无参构造函数创建对象
Object obj1 clazz.newInstance();// 使用带参数的构造函数创建对象
Constructor? constructor clazz.getConstructor(Collection.class);
CollectionString collection Arrays.asList(A, B, C);
Object obj2 constructor.newInstance(collection);System.out.println(obj1);
System.out.println(obj2);5. 动态调用方法
Method.invoke(Object obj, Object... args) 调用指定对象的该方法。
Class? clazz Class.forName(java.util.ArrayList);
Method method clazz.getMethod(add, Object.class);ArrayListString list new ArrayList();
method.invoke(list, Hello);
System.out.println(list); // 输出: [Hello]6. 动态访问和修改字段
Field.get(Object obj) 获取指定对象中此字段的值。
Field.set(Object obj, Object value) 设置指定对象中此字段的值。 class MyClass {private String field Initial Value;
}Class? clazz Class.forName(MyClass);
Field field clazz.getDeclaredField(field);
field.setAccessible(true); // 如果字段是私有的需要设置可访问MyClass obj new MyClass();
System.out.println(原始字段值: field.get(obj)); // 获取字段值field.set(obj, New Value); // 设置字段值
System.out.println(修改后的字段值: field.get(obj)); // 获取字段值结合注解与反射
注解与反射的结合非常常见尤其在框架中例如 Spring 和 Hibernate。通过反射机制你可以在运行时读取注解信息并根据这些信息执行特定的操作。
示例简单的依赖注入
以下示例展示了如何通过注解和反射实现简单的依赖注入
import java.lang.annotation.*;
import java.lang.reflect.*;// 定义注解
Retention(RetentionPolicy.RUNTIME)
Target(ElementType.FIELD)
interface Inject {
}// 服务类
class Service {public void serve() {System.out.println(Service is serving);}
}// 客户端类
class Client {Injectprivate Service service;public void doSomething() {service.serve();}
}// 注入依赖的工具类
public class DependencyInjector {public static void main(String[] args) throws Exception {Client client new Client();injectDependencies(client);client.doSomething();}public static void injectDependencies(Object obj) throws Exception {Class? clazz obj.getClass();for (Field field : clazz.getDeclaredFields()) { // 遍历client的所有字段(变量).if (field.isAnnotationPresent(Inject.class)) { // 获取带有Inject注解的变量, 把它注入到 Client 中field.setAccessible(true);Object dependency field.getType().getConstructor().newInstance();field.set(obj, dependency); // 通过field的set方法将service实例注入到client中}}}
}在这个示例中
Inject 注解用于标注需要注入的字段。DependencyInjector 类通过反射获取 Client 类中带有 Inject 注解的字段并动态实例化 Service 类的对象注入到 Client 类的实例中。Client 类调用 doSomething 方法时Service 类的实例已经被注入并可以使用。
总结
注解和反射是 Java 中非常强大和灵活的机制通过它们可以实现许多高级功能例如依赖注入、AOP、动态代理等。在实际开发中理解和熟练运用这些技术可以帮助你编写出更加灵活、可扩展的代码。
文章到这里就这束了~
其他文章地址:
快速入门springboot知识点汇总
springboot常用注解大全(超详细, 30个)
springboot websocket知识点汇总
spring cloud知识点汇总, 待更