栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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装饰器案例,实现代码如下:

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;



// 创建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 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());
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/731867.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号