注解与反射

注解与反射

一.注解
Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容,注解可以被一些解析工具或者编译工具进行解析,我们也可以声明注解在编译过程或执行时产生的作用。注解不仅包含了元数据,它还可以作用于程序运行过程中,注释解释器可以通过注解决定程序的执行顺序。

1.元注解
元注解的作用就是负责注解其他注解,Java5.0定义了四个标准的mete-annotion类型,它们被用来提供对其他annotion类型作说明

(1)Target
Target说明了Annoation所修饰的对象范围:Annotation可被用于packages,types(类,接口,枚举,Annotation类型),类型成员(方法,构造,方法,成员变量,枚举值),方法参数和本地变量(如循环变量,)在Annotation类型的声明中,使用了target可更加清晰明确器修饰的目标
取值有(ElementType)
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类,接口(包括注解类型)或enum声明

(2)Retention
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即被描述的注解在什么范围内有效)
取值:(RetentionPoicy)
1.SOURCE:在原码文件中有效
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即在运行时保留)
(3)Document
在产生DOC文档时使用,它是一个标记注解,没有成员
(4)Inherited
Inherited元注解是一个标记注解,阐述了某个被标注的类型是被继承的,
注意:@Inherited annotation类型是被标注过的class的子类所继承,类并不从他所实现的接口继承annotion,方法并不从它所重载的方法继承annotation
2.自定义注解
使用@Interface自定义注解时,自动继承了java.lang.annotation.Annotation,它用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数,方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型:Class,String,enum)可以通过default来声明参数的默认值

注意:只能用public或默认的default这两个访问权修饰,如果只有一个参数成员,最好把参数名称设为“value()”

package com.wang.demo2;

import java.lang.annotation.*;

public class MyTest {
    @Myannotion1
public void test(){

}
@MyAnnotion2("我喜欢你")
public void test2(){

}
}


@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface Myannotion1{
    String name() default "";
int age() default 0;
int id() default -1;
String[] schools() default {"小明","小花"};


    }
@Target(value = {ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})//作用域
@Retention(RetentionPolicy.RUNTIME)//运行时级别
@Documented
@Inherited
@interface MyAnnotion2{
    String value();
}

二.什么是反射
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所欲属性和方法,多余任意一个对象,都能够调用他的任意方法和属性,在具体的研发过程中,通过反射获取类的实例,大大提高系统的灵活性和扩展性,同时由于反射的性能较低,而且极大破坏了类的封装性(通过反射获取类的私有方法和属性)
注意:Class本身就是一个类,Class就是这个类的名称;public class MyTest{} 这里的class作为关键字,来表明Demo是一个类,数组类型一样的情况下,同个维度只有一个class对象
1.获取Class对象的三种方式
1.1Object–>getCLass();

1.2任何数据类型(包括基本数据类型)都有一个“静态”的class属性
1.3通过Class类的静态方法:(ForName)(String className)

package com.wang.demo2;

import java.sql.SQLOutput;

public class MyTest2 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 通过反射来获取class
        Class   c1 = Class.forName("com.wang.demo2.MyTest2");
        System.out.println(c1);
        //通过创建方式来获取
        User user = new User();
        Class c2 = user.getClass();
        System.out.println(c2);
        Class  c3 = MyTest2.class;
        System.out.println(c3);

    }

}
class User extends Object{
    private String name;
    private int age;
    private int id;

    public User() {
    }

    public User(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    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 int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}
package com.wang.demo2;

import java.lang.annotation.ElementType;

public class MyTest3 {
    public static void main(String[] args) {
        Class  c1 = Object.class; //类
        Class c2 = Comparable.class;//接口
        Class c3 = String.class;
        Class c4 = int.class;
        Class c5 = String[][].class; //二维数组
        Class c6 = ElementType.class; //枚举
        Class c7= Override.class; //注解
        Class c8 = Integer.class; //基本数据类型
        Class c9 = Void.class;// void
        Class c10 = Class.class;//Class

        int[] a = new int[10];
        int[] b = new int[100];


        Class c11 =a.getClass();
        Class c12 =b.getClass();

        //数组类型一样的情况下 , 同个维度 , 只有一个class对象
        System.out.println(c11==c12);
        System.out.println(c3==c5);

        System.out.println(c10);
        System.out.println(c11);
        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);
    }
}
输出结果:
true
false
class java.lang.Class
class [I
class java.lang.Object
interface java.lang.Comparable
class java.lang.String
int
class [[Ljava.lang.String;
class java.lang.annotation.ElementType
interface java.lang.Override
class java.lang.Integer
class java.lang.Void

2.通过反射获取构造方法并使用

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class MyTest4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("java.lang.Object");

        String name = c1.getName();//获得包名+类名
        String simpleName = c1.getSimpleName();//获得类名
        System.out.println(name);
        System.out.println(simpleName);

        Field[] fields = c1.getFields();//只能获得类的public属性
        for (Field field : fields) {
            System.out.println(field);
        }

        Field[] declaredFields = c1.getDeclaredFields();//获得类的全部属性
        
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        Field name1 = c1.getDeclaredField("equals");//获得指定的属性值
        name1.setAccessible(true);//解除私有限定
        System.out.println(name1);
        Method[] methods = c1.getMethods();//获取本类所有的public方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("===============================================");
        Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的所有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("=========================================================");
        Constructor constructor = c1.getConstructor(null);
        System.out.println(constructor);//获得无参构造
        Constructor constructor1 = c1.getConstructor(String.class, int.class,int.class);
        System.out.println(constructor1);


    }
}

3.通过动态构造对象,调用方法

package com.wang.demo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyTest5 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> c1 = Class.forName("com.wang.demo2.User");
        //通过动态调用构造方法构造对象
       User user = (User) c1.newInstance();
        System.out.println("=======================================");
        //通过有参构造创建对象
        Constructor<User> declaredConstructor = (Constructor<User>) c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user1 = declaredConstructor.newInstance("张三", 001, 29);
        System.out.println("===========================================");
        //调用普通方法
     User user2= (User) c1.newInstance();
        Method setName = c1.getDeclaredMethod("setName", String.class);
        setName.invoke(user2,"李四");
        System.out.println(user2.getName());
        System.out.println("==============================================");
        //操作属性
        User user3 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        name.setAccessible(true);//关闭监测
        name.set(user3,"王五");
        System.out.println(user3.getName());
        

    }
}

4.设置输出字体颜色

public class MyTest6{
    public static void main(String[] args) {
        System.out.println("\u001b[31m 杜兰特");//红色
        System.out.println("\u001b[1;42m 你好");//控制输出背景颜色
        System.out.println();
        //有下划线
        System.out.println("\033[32;4m 中国 \033[0m");
        System.out.println("\033[30;4m 美国 \033[0m");
        System.out.println("\033[31;4m 英国 \033[0m");
    }
}

输出结果:
在这里插入图片描述

5.测试泛型获取泛型

public class MyTest7 {
    public void test01(Map<String, User> map, List<User> list) {
        System.out.println("这是test01");
    }

    public Map<Integer, User> test02() {
        System.out.println("这是test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        //获得指定方法的泛型信息
        Method method = MyTest7.class.getDeclaredMethod("test01", Map.class, List.class);

        //获得泛型参数信息
        Type[] t = method.getGenericExceptionTypes();
        for (Type type : t) {
            System.out.println("1" + type);
            if (type instanceof ParameterizedType) {
                Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
                //获得真实的类型参数
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println("Really" + actualTypeArgument);
                }
            }
        }
        //获得返回值泛型信息

        Method method1 = MyTest7.class.getMethod("test02");
        //获得泛型参数类型信息
        //获得泛型返回值信息
        Type genericReturnType = method1.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();

            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("真实的返回值泛型类型" + actualTypeArgument);
            }
        }
    }
}

6.测试对象关系映射

public class Test{
    public static void main(String[] args) throws Exception {
        //通过反射获取注解信息
        Class c1 = Class.forName("com.kuang.reflection.Student2");

        Annotation[] annotations = c1.getAnnotations();//获得这个类的所有注解信息
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        //获得注解的值
        //通过注解的 value方法 获得注解的值
        Annotation annotation = c1.getAnnotation(TableKuang.class);
        TableKuang annotation1 = (TableKuang) annotation;
        System.out.println(annotation1.value());

        Field field = c1.getDeclaredField("id");
        System.out.println(field);
        //获得字段的注解
        FieldKuang annotation2 = field.getAnnotation(FieldKuang.class);
        //获得注解的参数信息
        System.out.println(annotation2.columnName());
        System.out.println(annotation2.length());
        System.out.println(annotation2.type());

    }
}

//学生的实体类
//db : database -->数据库
@TableKuang("db_student")
class Student2{

    @FieldKuang(columnName = "id",type = "int",length = 10)
    private int id;
    @FieldKuang(columnName = "db_age",type = "int",length = 3)
    private int age;
    @FieldKuang(columnName = "name",type = "varchar",length = 20)
    private String name;

    public Student2() {
    }
    public Student2(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    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 TableKuang{
    String value();
}

//字段类的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldKuang{

    //参数类型  参数名
    String columnName();//列名
    String type();//类型
    int length();//长度

}
本文详细介绍了如何利用Python语言结合MySQL数据库开发一个学生管理系统。通过这一过程,读者不仅能够掌握系统设计的基本思路,还能学习到如何使用Python进行数据库操作。该系统涵盖了用户界面设计、数据验证以及数据库的增删改查等多个关键环节。 Python作为一种高级编程语言,以简洁易懂著称,广泛应用于数据分析、机器学习和网络爬虫等领域,同时也非常适合用于快速开发数据库管理应用。MySQL是一个广泛使用的开源关系型数据库管理系统,具有轻量级、高性能、高可靠性和良好的编程语言兼容性等特点,是数据存储的理想选择。在本系统中,通过Python的pymysql库实现了MySQL数据库的交互。 pymysql是一个Python第三方库,它允许程序通过类似DB-API接口连接MySQL数据库,执行SQL语句并获取结果。在系统中,通过pymysql建立数据库连接,执行SQL语句完成数据的增删改查操作,并对结果进行处理。 系统采用命令行界面供用户操作。程序开始时,提示用户输入学生信息,如学号、姓名和各科成绩,并设计了输入验证逻辑,确保数据符合预期格式,例如学号为1至3位整数,成绩为0至100分的整数。 数据库设计方面,系统使用名为“test”的数据库和“StuSys”表,表中存储学生的学号、姓名、各科成绩及总成绩等信息。通过pymysql的cursor对象执行SQL语句,实现数据的增删改查操作。在构建SQL语句时,采用参数化查询以降低SQL注入风险。 系统在接收用户输入时进行了严格验证,包括正则表达式匹配和数字范围检查等,确保数据的准确性和安全性。同时,提供了错误处理机制,如输入不符合要求时提示用户重新输入,数据库操作出错时给出相应提示。 在数据库操作流程中,用户可以通过命令行添加学生信息或删除记录。添加时会检查学号是否重复以避免数据冲突,删除时需用户确认。通过上述分析,本文展示了从
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值