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