python装饰器、java装饰器模式、java标签的Demo对比

1、python装饰器


def show(function):
    def temp(x, y):
        print("===============")
        z = function(x, y)
        return z

    return temp


@show
def myAdd(a, b):
    return a + b


@show
def mySubtract(a, b):
    return a - b


print(myAdd(3, 4))
print(mySubtract(3, 4))

2、java装饰器模式

同python装饰器案例,实现代码如下:

/**
 * @author Lenovo
 * @date 2022/2/7
 * @Function:实现装饰器模式
 */
interface MyFunction{
    int function(int x, int y);
}

class MyAdd implements MyFunction{

    @Override
    public int function(int x, int y) {
        return x+y;
    }
}

class MySubtract implements MyFunction{

    @Override
    public int function(int x, int y) {
        return x-y;
    }
}

abstract class ShowDecorator implements MyFunction{
    protected MyFunction func;

    public ShowDecorator(MyFunction func){
        this.func=func;
    }

    @Override
    public int function(int x, int y) {
        return func.function(x, y);
    }
}

class Show extends ShowDecorator{
    public Show(MyFunction func) {
        super(func);
    }
    @Override
    public int function(int x, int y) {
        System.out.println("================");
        return func.function(x, y);
    }
}

public class Solution {
    public static void main(String[]args){
        int result;
        result = new MyAdd().function(3,4);
        System.out.println(result+"\n");

        result = new MySubtract().function(3,4);
        System.out.println(result+"\n");

        ShowDecorator show  = new Show(new MyAdd());
        result=show.function(3,4);
        System.out.println(result+"\n");

        show  = new Show(new MySubtract());
        result=show.function(3,4);
        System.out.println(result+"\n");
    }
}

3 java注解

java的注解与python的装饰器不同,java确实没有标签表示装饰器的方法.

注解注意事项:

1、自定义注解只有一个属性时,且属性名为value时,赋值时value可省略。
2、自定义注解只有一个属性时,且属性名不为value时,赋值时应与属性名保持一致
3、自定义注解有多个属性时,赋值时应与属性名保持一致。

参考学习资料:

Java 注解入门实例 && 注解传参_wp94302948的博客-CSDN博客_java注解实现变量参数传递

@value注解_Java系列之注解_weixin_39609500的博客-CSDN博客

通过类的函数遍历获取

案例:通过2个自定义注解注入参数


import java.lang.annotation.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Target({ElementType.PARAMETER ,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@interface A {
    //String value();
    String name() default "bingone";
    int age() default 20;
}

@Target({ElementType.PARAMETER ,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface B {
    //String value();
    String name() default "bingone";
}

class DataClass {
    public String name;
    public int age;
    public DataClass(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
}

class RunClass {
    public static void run(@A(name = "str") String string, @B(name = "age")int age){
        System.out.println("In run Method string:" + string + "\tage:" + age);
    }
}

public class Solution{
    public static void parseMethod(DataClass data,Object obj,String mthname){
        //验证是否有注解
        //若有则两种方法:
        //1. 在编译时刻已经有了对应的表,查表即可
        //2. 如下的遍历方式。
        if(obj instanceof RunClass){
            String string = null;
            int Age = 0;
            Method[] methods = (Method[])obj.getClass().getMethods();
            for(Method method :methods){
                if(method.getName().equals(mthname)){

                    Annotation[][] annotations = method.getParameterAnnotations();
                    for(Annotation[] tt : annotations){
                        for(Annotation t:tt){
                            if(t instanceof A){
                                string = data.name;
                            }else if(t instanceof B){
                                Age = data.age;
                            }
                        }
                    }
                    try {
                        method.invoke(new RunClass(), string, Age);
                    } catch (InvocationTargetException | IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception, RuntimeException { // 主方法
        //不直接传参数,而是将一个类中的数据传入
        DataClass dc = new DataClass("gg_gogoing", 20);
        parseMethod(dc, new RunClass(), "run");
    }

}

通过类内的变量获取

案例:自动生成数据库表格的字段

import java.io.Serializable;
import java.lang.annotation.*;
import java.lang.reflect.Field;

/**
 * @author Lenovo
 * @date 2022/2/7
 * @Function:使用Java注解开发实现自动创建数据库表格
 */

// 创建Column注解,表示数据库中的字段信息
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface Column{
    String columnName();
    String dataType();
    int dataLength() default 10;
    String  constraint() default "";
}

//创建Table注解,表示数据库中的表
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
    String tableName();
}

//创建JavaBen类,使用定义的注解
@Table(tableName = "Table_User")
class User  implements Serializable{
    @Column(columnName = "id",dataType="int",dataLength = 6,constraint = "primary key")
    private int id;

    @Column(columnName = "username",dataType = "varchar",dataLength = 10,constraint = "unique")
    private String name;

    @Column(columnName = "password",dataType = "varchar",dataLength = 10)
    private String password;
}

class AutoCreateTable{
    /**
     * 通过反射操作,获取类中携带的注解信息.根据读取到的信息生成数据库的建表语句
     */
    public static String buildSql() {
        // 准备数据库的建表语句
        StringBuilder str = new StringBuilder("CREATE TABLE ");
        // 获取User类对应的Class对象
        Class<User> clazz = User.class;

        // =============================================================
        // 一.获取User类中携带的@Table注解,以此来获取表名信息
        // (1)获取User类中携带的Table注解
        Table table = (Table) clazz.getAnnotation(Table.class);
//        System.out.println(table);
        // (2)获取Table注解中的的属性信息
        String tableName = table.tableName();// 获取表名信息
//        System.out.println(tableName);
        // (3)把表名信息拼接到SQL语句中
        str.append(tableName).append(" (");
        // =============================================================
        // 二:获取User类中携带的Column注解,来获取字段的相关信息
        // (1)获取类中声明的所有的属性
        Field[] fields = clazz.getDeclaredFields();
        // (2)遍历保存所有属性的Field的数组,取出每个属性
        for (Field field : fields) {
            // (3)判断属性中是否使用了Column注解
            if (field.isAnnotationPresent(Column.class)) {
                // (4)获取属性中使用的Column注解
                Column column = field.getAnnotation(Column.class);
                
                // (5)获取注解中携带的字段信息
                String columnName = column.columnName(); // 获取字段名信息
                String columnType = column.dataType(); // 获取字段类型信息
                int columnLength = column.dataLength(); // 获取字段长度信息
                String columnConstraint = column.constraint(); // 获取字段约束信息
               
                // (6)把字段的相关信息拼接到SQL语句中
                str.append(columnName + " " + columnType + " (" + columnLength + ") " + columnConstraint + ",");
            }
        }
        // 去除SQL中最末尾的逗号,并且关闭SQL语句中的()
        return str.substring(0, str.length() -1) + ")";//截取字符串语句。
    }
}

public class Solution {
    public static void main(String[]args){
        System.out.println(AutoCreateTable.buildSql());
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

广大菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值