注解(Annotation)
Java 注解(Annotation)是一种特殊的语言构造,用于为代码元素(如类、方法、字段等)提供元数据,通常不直接影响程序的逻辑执行。它们可以被编译器、框架或工具解析,用于执行特定操作,如自动化配置、代码生成、验证等。Java 提供了内置的注解(如 @Override
、@Deprecated
)和允许用户自定义注解。注解的处理方式可以在编译时或运行时进行,常用于框架配置、自动化处理和代码文档生成等场景
@注解名 (参数)
注释和注解的区别为注释是给编程人员看的,用于解释代码含义的,而注解是给其他程序看的,用于帮助其他程序读懂该段代码,总结就是注释是帮助人解释代码,注解就是帮助程序解释代码
内置注解
内置注解是 Java 提供的预定义注解,它们通常用于编译时检查、代码优化或者提供额外的元数据。Java 标准库中提供了几种常用的内置注解,它们有特定的用途和行为,帮助开发者提高代码的可读性、可维护性并减少错误
Java 的常见内置注解包括 @Override
、@Deprecated
、@SuppressWarnings
以上主要注意@Override
重写注解和@SuppressWarnings
警告镇压注解,而@Deprecated
早已被废弃
元注解
元注解(Meta-Annotation)是用于描述其他注解的注解。它们定义了注解的使用方式和生命周期,通常用于自定义注解时。
-
@Retention
:指定注解的保留策略,决定注解在哪个阶段可用。可以是SOURCE
(仅在源码中可见),CLASS
(在编译后仍可用,但不会被加载到 JVM 中),RUNTIME
(在运行时可用,通常用于反射)。 -
@Target
:指定注解可以应用于哪些 Java 元素,如类、方法、字段等。通过ElementType
枚举进行定义。 -
@Inherited
:表示子类可以继承父类的注解,适用于类级别的注解。 -
@Documented
:表示注解应包含在 JavaDoc 中,生成的文档会包含该注解的详细信息。
package org.example;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 自定义注解,作用于方法和类上,运行时
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
// 注解的参数定义:参数类型 参数名() default 默认值
String name() default "李华";
// 默认值 -1 表示不存在
int age() default -1;
}
反射(Reflection)
反射是 Java 提供的一种在运行时动态获取类的信息、创建对象、调用方法和访问字段的机制。它通过 Class
类和相关的 API 允许程序在运行时检查和操作类的结构,而无需在编译时明确这些信息。反射广泛应用于框架设计、动态代理和工具开发等领域,但由于性能开销和安全性问题,使用时需要谨慎
动态和静态语言
动态语言是指在运行时可以改变其结构的编程语言,如新增函数、对象或修改已有结构。常见的动态语言有 Python、JavaScript、PHP、C# 等。相比之下,静态语言如 Java、C、C++ 其结构在运行时是不可变的,编译时类型和结构已经确定。然而,Java 也具有一定的动态性,尤其通过反射机制,能够在运行时进行一定的结构调整,具备类似动态语言的一些特性
Java作为一门特殊的静态语言,通过反射能表现出准动态性
Java中万物皆对象,描述Java程序编译生成的Class文件的对象就是Class类对象,因此Class文件,成员变量,成员方法和构造方法的对于的类为Class类,Field类,Method类和Constructor类
类的加载机制:父类对象->子类对象->main方法->静态成员->反射
正常是先定义类,然后通过类去实例化对象,而反射机制允许通过对对象的解析反推出类的结构,而无需一开始定义类的结构
package org.example;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Student{
private String name = "李华";
private int age = 18;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
Student stu = new Student();
Class c = null;
// 常见四种获取class类的方法
c = stu.getClass();
// org.example.Student为类的全限定名
c = Class.forName("org.example.Student");
c = Student.class;
// 反射构造方法
// 获取所有的非私有构造方法
// getDeclared*,获取所有的包括私有的,如getDeclaredConstructors,获取所有的构造方法
Constructor[] cs = c.getConstructors();
for (Constructor ctor : cs) {
System.out.println(ctor);
}
// 无参构造
Constructor ctor = c.getConstructor();
// 有参构造
ctor = c.getConstructor(String.class,int.class);
// 通过构造方法创建实例
Student s = (Student) ctor.newInstance("小明",18);
System.out.println(s.toString());
// 获取所有成员方法包括父类的,非私有
Method[] ms = c.getMethods();
for (Method m : ms) {
System.out.println(m);
}
// 获取指定方法,传入方法名和参数,用于区分不同方法和重载方法
Method m = c.getMethod("setName", String.class);
// 执行对应的方法,传入一个对象和方法参数
m.invoke(s,"李雷");
System.out.println(s.toString());
Field[] fs = c.getFields();
// 获取所有成员变量
for (Field f : fs) {
System.out.println(f);
}
// 获取指定成员变量
Field f = c.getDeclaredField("name");
// 运行操作私有成员变量
f.setAccessible(true);
f.set(s,"韩梅梅");
System.out.println(s.toString());
}
}
标签:毕设,Java,name,age,Student,第四天,注解,public
From: https://www.cnblogs.com/liyiyang/p/18670478