解决Java硬编码的问题

使用过 mybatis-plus 都知道其可以使用jdk8中引入的方法引用动态获取对象属性的字段名称,从而解决了硬编码的问题!我们也可以简单的实现一下

一、新建一个函数式接口

/**
 * @author wfd
 * @description
 * @create 2021/5/2 0:17
 */
@FunctionalInterface
public interface DynamicFieldFunction<T,R> extends Function<T, R>, Serializable {

}

二、新建一个 DynamicField 类,具体实现如何获取名称

package com.wfd.study.func;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wfd
 * @description
 * @create 2021/5/2 0:19
 */
public class DynamicField {
	public static final String PREFIX_GET = "get";
	public static final String PREFIX_IS = "is";
	private static Logger log = LoggerFactory.getLogger(DynamicField.class);

	/**
	 * 获取驼峰式的字段名
	 * @param dynamicField
	 * @param <T>
	 * @param <R>
	 * @return
	 */
	public static <T, R> String getFieldColumn(DynamicFieldFunction<T, R> dynamicField) {
		// 直接调用writeReplace
		Method writeReplace = null;
		String methodName = null;
		try {
			writeReplace = dynamicField.getClass().getDeclaredMethod("writeReplace");
			writeReplace.setAccessible(true);
			Object sl = writeReplace.invoke(dynamicField);
			SerializedLambda serializedLambda = (SerializedLambda) sl;
			methodName = serializedLambda.getImplMethodName();
			if (methodName.startsWith(PREFIX_GET)) {
				methodName = methodName.substring(PREFIX_GET.length());
			} else if (methodName.startsWith(PREFIX_IS)) {
				methodName = methodName.substring(PREFIX_IS.length());
			}
		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
			log.error("动态获取属性名称失败:{}", e.getMessage());
			return "";
		}
		return firstToLowerCase(methodName);
	}

	/**
	 * 将驼峰式名称转为下划线命名,主要用于Map集合中根据key获取值,也可解决硬编码的问题
	 * @param dynamicField
	 * @param <T>
	 * @param <R>
	 * @return
	 */
	public static <T, R> String getFieldUnderline(DynamicFieldFunction<T, R> dynamicField) {
		// 直接调用writeReplace
		Method writeReplace = null;
		String methodName = null;
		try {
			writeReplace = dynamicField.getClass().getDeclaredMethod("writeReplace");
			writeReplace.setAccessible(true);
			Object sl = writeReplace.invoke(dynamicField);
			SerializedLambda serializedLambda = (SerializedLambda) sl;
			methodName = serializedLambda.getImplMethodName();
			if (methodName.startsWith(PREFIX_GET)) {
				methodName = methodName.substring(PREFIX_GET.length());
			} else if (methodName.startsWith(PREFIX_IS)) {
				methodName = methodName.substring(PREFIX_IS.length());
			}
		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
			log.error("动态获取属性名称失败:{}", e.getMessage());
			return "";
		}
		return camelToUnderline(methodName);
	}


	public static String camelToUnderline(String camelString){
		if (null == camelString || "".equals(camelString)) {
			return camelString;
		}
		camelString = String.valueOf(camelString.charAt(0)).toUpperCase().concat(camelString.substring(1));

		StringBuilder sb = new StringBuilder();
		Pattern pattern = Pattern.compile("[A-Z]([a-z\\d]+)?");
		Matcher matcher = pattern.matcher(camelString);
		while (matcher.find()) {
			String word = matcher.group();
			sb.append(word.toLowerCase());
			sb.append(matcher.end() == camelString.length() ? "" : "_");
		}
		return sb.toString();
	}

	private static String firstToLowerCase(String s) {
		if (Character.isLowerCase(s.charAt(0)))
			return s;
		else
			return Character.toLowerCase(s.charAt(0)) + s.substring(1);
	}
}


三、测试

public class Test {
	public static void main(String[] args) throws Exception {
		String fieldColumn = DynamicField.getFieldColumn(Spu::getName);
		// 输出 name
		System.out.println("fieldColumn = " + fieldColumn);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值