一、注解(Annotation)
1.1 注解 (Annotation)
作用:不是程序本身,可以对程序作出解释。可以被其他程序读取。
格式:@注释名,还可以添加一些参数值
1.2 内置注解
@Override 重写的注解
@Deprecated 不推荐程序员使用,但是可以使用,或者存在更好的方式
@Suppress Warnings("") 镇压警告
1.3 元注解
元注解的作用是负责注解其他注解,java定义了4个标准的meta-annotation
@Target :用于描述注解的使用范围(被描述的注解可以用在什么地方)
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention :表示需要在什么级别保存该注释信息,用于描述注解的生命周期
runtime>class>sources @Retention(RetentionPolicy.RUNTIME)
@Document:表示是否将我们的注解生成在Javadoc中
@Inherited:子类可以继承父类的注解
1.4 自定义注解
使用 @interface 自定义注解时,自动继承了java.lang.annotation.Annotation接口。
-
格式:public @ interface 注解名{ 注解的参数:参数类型 + 参数名()}
-
方法的名称就是参数的名称
-
返回值类型就是参数的类型(class,string,enum)
-
可以通过default来声明参数的默认值
-
如果只有一个参数成员,一般参数名为value
-
注解元素必须要有值,我们定义注解元素时,经常使用空字符串,0作为默认值
二、反射机制(Java. Reflection)
java是一门静态语言,但是我们可以利用反射机制获得类似动态语言的特性。
通过对象反射求出类的名称
2.1 Java Reflection
- Reflection是java被视为动态语言的关键,反射机制允许程序在执行期借助Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
Class c = Class.forName(“java.lang.String”)
2.2 Class类
对象照镜子后可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。
class本身也是一个类,class对象只能由系统建立对象。
package com.reflection;
//获取class的实例的方法
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是:"+person.name);
//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1);
System.out.println(c1.hashCode());
//方式二:forname获得
Class c2 = Class.forName("com.reflection.Student");
System.out.println(c2);
System.out.println(c2.hashCode());
//方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3);
System.out.println(c3.hashCode());
//方式四:基本内置类型的包装类都有一个Type属性
Class<Integer> c4 = Integer.TYPE;
System.out.println(c4);
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person() {
}
public Person(String name){
this.name=name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person{
public Student() {
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher() {
this.name = "老师";
}
}
所有类型的class
//所有类型的class
public class Test02 {
public static void main(String[] args) {
Class c1 = Object.class; //类
Class c2 = Comparable.class; //接口
Class c3 = String[].class; //一维数组 只要元素类型和维度一样,就是同一个class
Class c4 = int[][].class; //二维数组
Class c5 = Override.class; //注解
Class c6 = ElementType.class; //枚举
Class c7 = Integer.class; //基本数据类型
Class c8 = void.class; //void
Class c9 = Class.class; //Class
}
}
三、获得类的信息
//方法一:
Class c1 = Class.forName("com.xq.reflection.User");
//方法二:
User user = new User();
c1 = user.getClass();
//获得类的名字
System.out.println(c1.getName());//获得包名+类名
System.out.println(c1.getSimpleName());//获得类名
//获得类的属性
Field[] fields = c1.getFields();
invoke -> 调用 , xxxMethod.invoke(对象名,参数值) 调用方法
invoke:激活的意思(对象,“方法的值”)
不能直接操作私有属性,我们需要关闭程序的安全监测
Accessible:允许访问的/可访问的/可连接的/可取数的
setAccessible(true) -> 设置为可直接访问的
方法、字段、构造器都有上面的方法
关闭检测提高反射的速率,提高性能
反射操作泛型
ParameterizedType
GenericArrayTyp
ORM
Object relationship Mapping —>对象关系映射
类和表结构对应
属性和字段对应
对象和记录对应
获得类指定的属性的注解,通过name属性获得它的注解,后面所学的框架会在类里进行大量注解,然后通过反射框架读取注解生成相应的信息,可以获取数据库的字段然后可以进行curd
package com.reflection;
import javafx.scene.control.Tab;
import java.lang.annotation.*;
import java.lang.reflect.Field;
//练习反射操作注解
public class Test03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.reflection.Student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解value的值
Tablexq tablexq = (Tablexq)c1.getAnnotation(Tablexq.class);
String value = tablexq.value();
System.out.println(value);
//获得类指定的属性的注解,通过name属性获得它的注解,后面所学的框架会在类里进行大量注解,然后通过反射框架读取注解生成相应的信息
Field f = c1.getDeclaredField("name");
Fieldxq annotation = f.getAnnotation(Fieldxq.class);
System.out.println(annotation.colimnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
//给类添加注解,上面通过反射获得的注解就是获得注解的路径加上注解名和属性
@Tablexq("db_student")
class Student2{
@Fieldxq(colimnName = "db_id",type = "int",length = 10)
private int id;
@Fieldxq(colimnName = "db_age",type = "int",length = 10)
private int age;
@Fieldxq(colimnName = "db_name",type = "varchar",length = 3)
private String name;
public Student2() {
}
public Student2(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tablexq{
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldxq{
String colimnName();
String type();
int length();
}