ロンボク島の落とし穴を知る
java Basic Tutorial コラムでは、簡単に使える Lombok の落とし穴を紹介します。
まえがき
昨年このプロジェクトに Lombok プラグインが導入されました。これにより、手が本当に解放され、いくつかの反復的な単純なタスク (Getter、 Setter, toString などのメソッド記述) を使用していましたが、使用する過程でいくつかの落とし穴も発見されました。最初は Lombok 問題であることに気づきませんでした。後に、対応する他のコンポーネントのソース コードを追跡し、それはロンボク島の問題であることがわかりました。
Setter-Getter メソッドの落とし穴
問題発見
プロジェクトでは主に Lombok の Setter-Getter メソッドのアノテーションを使用します。これは、結合アノテーション @Data です。 , しかし、プロジェクトでは Mybatis を使用してデータを挿入するプロセス中に問題が発生しました。問題は次のように説明されています:
我们有个实体类: @Data public class NMetaVerify{ private NMetaType nMetaType; private Long id; ....其他属性 }复制代码
Mybatis を使用してデータを挿入すると、他の属性は正常に挿入できることがわかりました。しかし、nMetaType 属性はデータベース内にあり、常に null でした。
解決策
Mybatis で SQL の挿入に対応するメソッドを呼び出すプロジェクト コードをデバッグすると、NMetaVerify オブジェクトの nMetaType 属性にはまだデータがあることがわかりますが、挿入を実行した後、データベース nMetaType フィールドは常に null です。最初は列挙型が間違って記述されていると思いました。同様に列挙型を持つ他のフィールドを確認した後、それらはデータベースに正常に挿入できるため、さらに混乱します。 .そこでMybatisのソースコードを辿ってみたところ、Mybatisではリフレクションを利用してnMetaType属性を取得しており、getxxxxメソッドを使用して取得していることが分かりましたが、nMetaTypeのgetメソッドが必要なgetxxxxメソッドとは少し違うようであることが分かりました。 Mybatis著、同じです。問題が見つかりました!
理由
最初の文字が小文字で 2 番目の文字が大文字である属性に対して Lombok によって生成された get-set メソッドは Mybatis によって生成され、idea または get-set メソッドは正式に認められています。 Java の違い:
#Lombok生成的Get-Set方法 @Data public class NMetaVerify { private Long id; private NMetaType nMetaType; private Date createTime; public void lombokFound(){ NMetaVerify nMetaVerify = new NMetaVerify(); nMetaVerify.setNMetaType(NMetaType.TWO); //注意:nMetaType的set方法为setNMetaType,第一个n字母大写了, nMetaVerify.getNMetaType(); //getxxxx方法也是大写 } }复制代码
#idea,Mybatis,Java官方默认的行为为: public class NMetaVerify { private Long id; private NMetaType nMetaType; private Date createTime; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public NMetaType getnMetaType() {//注意:nMetaType属性的第一个字母小写 return nMetaType; } public void setnMetaType(NMetaType nMetaType) {//注意:nMetaType属性的第一个字母小写 this.nMetaType = nMetaType; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }复制代码
Mybatis (バージョン 3.4.6) は get-set メソッドを解析して属性名のソース コードを取得します:
package org.apache.ibatis.reflection.property; import java.util.Locale; import org.apache.ibatis.reflection.ReflectionException; /** * @author Clinton Begin */ public final class PropertyNamer { private PropertyNamer() { // Prevent Instantiation of Static Class } public static String methodToProperty(String name) { if (name.startsWith("is")) {//is开头的一般是bool类型,直接从第二个(索引)开始截取(简单粗暴) name = name.substring(2); } else if (name.startsWith("get") || name.startsWith("set")) {//set-get的就从第三个(索引)开始截取 name = name.substring(3); } else { throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'."); } //下面这个判断很重要,可以分成两句话开始解释,解释如下 //第一句话:name.length()==1 // 对于属性只有一个字母的,例如private int x; // 对应的get-set方法是getX();setX(int x); //第二句话:name.length() > 1 && !Character.isUpperCase(name.charAt(1))) // 属性名字长度大于1,并且第二个(代码中的charAt(1),这个1是数组下标)字母是小写的 // 如果第二个char是大写的,那就直接返回name if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);//让属性名第一个字母小写,然后加上后面的内容 } return name; } public static boolean isProperty(String name) { return name.startsWith("get") || name.startsWith("set") || name.startsWith("is"); } public static boolean isGetter(String name) { return name.startsWith("get") || name.startsWith("is"); } public static boolean isSetter(String name) { return name.startsWith("set"); } }复制代码
Mybatis は get-set メソッドを解析して次のようにします属性名をテストします
@Test public void foundPropertyNamer() { String isName = "isName"; String getName = "getName"; String getnMetaType = "getnMetaType"; String getNMetaType = "getNMetaType"; Stream.of(isName,getName,getnMetaType,getNMetaType) .forEach(methodName->System.out.println("方法名字是:"+methodName+" 属性名字:"+ PropertyNamer.methodToProperty(methodName))); } #输出结果如下: 方法名字是:isName 属性名字:name 方法名字是:getName 属性名字:name 方法名字是:getnMetaType 属性名字:nMetaType //这个以及下面的属性第二个字母都是大写,所以直接返回name 方法名字是:getNMetaType 属性名字:NMetaType复制代码
解決策
1.修改属性名字,让第二个字母小写,或者说是规定所有的属性的前两个字母必须小写 2.如果数据库已经设计好,并且前后端接口对接好了,不想修改,那就专门为这种特殊的属性使用idea生成get-set方法复制代码
@Accessor(chain = true) アノテーションの問題
問題発見
easyexcel(github.com/)を使用してエクスポートします。 alibaba/eas…) 確認したところ、以前のエンティティクラスのエクスポートは正常でしたが、新しく追加されたエンティティクラスは正常ではありませんでした。比較した結果、新しく追加されたエンティティクラスには @Accessor(chain = true) アノテーション. 私たちの主な目的は、チェーンで set メソッドを呼び出すと便利です:
new UserDto() .setUserName("") .setAge(10) ........ .setBirthday(new Date());复制代码
Reason
easyexcel の最下層は、リフレクション ツールキットとして cglib を使用します:
com.alibaba.excel.read.listener.ModelBuildEventListener 类的第130行 BeanMap.create(resultModel).putAll(map); 最底层的是cglib的BeanMap的这个方法调用 abstract public Object put(Object bean, Object key, Object value);复制代码
ただし、cglib は Java の rt A メソッドを使用します。jar 内の Introspector クラス:
# Introspector.java 第520行 if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) { pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null); //下面这行判断,只获取返回值是void类型的setxxxx方法 } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) { // Simple setter pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method); if (throwsException(method, PropertyVetoException.class)) { pd.setConstrained(true); } }复制代码
解決策
1.去掉Accessor注解 2.要么就等待easyexcel的作者替换掉底层的cglib或者是其他,反正是支持获取返回值不是void的setxxx方法就行复制代码
関連する無料学習の推奨事項: Java の基本チュートリアル ##
以上がロンボク島の落とし穴を知るの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

専門的なガイダンス: Lombok プラグインを Eclipse にインストールするための専門家のアドバイスと手順。特定のコード例が必要です。 概要: Lombok は、アノテーションを通じて Java コードの作成を簡素化し、いくつかの強力なツールを提供する Java ライブラリです。この記事では、Eclipse で Lombok プラグインをインストールして構成する方法の手順を読者に紹介し、読者が Lombok プラグインをよりよく理解して使用できるように、いくつかの具体的なコード例を示します。まず Lombok プラグインをダウンロードします。

クイック スタート: Lombok プラグインを Eclipse にインストールするための簡単なチュートリアル (特定のコード サンプルが必要) Java プロジェクトの開発プロセスでは、Lombok は実用的なプラグインとしてよく使用されます。 Lombok は、Java コードを簡素化し、定型コードの作成を減らし、開発効率を向上させるのに役立ちます。この記事では、Eclipse に Lombok プラグインをインストールして構成する方法を紹介し、具体的なコード例を示します。ステップ 1: Lombok プラグインをダウンロードする まず、Lombok 公式 Web サイトから Lombok プラグインをダウンロードする必要があります。

LombokLombok は Java コードを単純なアノテーションの形で簡略化できるため、開発者の開発効率が向上します。それ自体は優れた Java コード ライブラリです。Lombok は、Java コーディングを簡素化するために便宜的な構文シュガーを使用し、Java コードを合理化する方法を提供します。ただし、Lombok は標準の Java ライブラリではありません。 Web 開発中に Java クラスを記述する必要がある場合、対応するゲッター/セッター、コンストラクター、equals およびその他のメソッドを追加するのに時間がかかります。属性が多い場合、ゲッター/セッター メソッドも多数存在します。これらは非常に長く、技術的な内容があまりありません。属性を変更すると、対応するメソッドの変更を忘れがちです。

完全ガイド: Eclipse 用 Lombok プラグインをインストールする方法、特定のコード例が必要 はじめに: Eclipse は、Java 開発用に広く使用されている統合開発環境 (IDE) です。 Lombok は、開発効率を向上させるためにいくつかの退屈なコードを自動化できる Java ライブラリです。この記事では、Eclipse に Lombok プラグインをインストールする方法を詳しく説明し、具体的なコード例を示します。ステップ 1: Lombok プラグインをダウンロードし、Eclipse を開き、「ヘルプ」を選択します。

実践的なヒント: Lombok プラグインを Eclipse に簡単にインストールする方法、具体的なコード例が必要です 日常の Java 開発では、メインの統合開発環境として Eclipse を使用することがよくあります。実際の開発では、Getter メソッドや Setter メソッドを手動で記述するなど、面倒な操作が発生することがあります。これらの操作を簡素化するために、Lombok プラグインを使用すると、これらのコードを自動的に生成できます。 Eclipse に簡単にインストールして設定する方法は次のとおりです。

Lombok とは何ですか? Lombok は、コード開発の労力を軽減するために設計された Java ライブラリです。これは、toString メソッド、equals メソッドなど、pojo の最も一般的なセッター/ゲッター メソッドなど、Java の肥大化したテンプレート コードを排除するためのいくつかの簡単なアノテーションを提供します。また、JDK7 がすでに存在する場合でも、ストリームを閉じるのにも役立ちます。 TWR の機能は にありますが、このパッケージはチェックしてみる価値があります。いくつかの簡単な注釈を介して、コンパイル中にテンプレート コードがプログラムに書き込まれます。 Eclipse を使用すると、アウトライン ウィンドウで生成されたメソッドが表示されますが、ソース コードはクリーンです インストールするには、まず lombok 公式 Web サイトにアクセスして、jar パッケージをダウンロードします。 jarパッケージをダウンロードするだけです

Java は、さまざまな種類のアプリケーションの開発に広く使用されている、一般的に使用されるプログラミング言語です。 Java API は Java 言語の中核部分の 1 つであり、アプリケーションの開発と展開のプロセスを高速化できる、再利用可能な多くのコードとライブラリを開発者に提供します。 Java API の開発プロセスでは、多くの場合、コードの可読性と保守性を向上させるためにコーディングを簡素化するためにいくつかのツールやテクニックを使用する必要があります。 Lombok は Java で使用できる非常に実用的な Java ライブラリです。

注釈の例 1. @ToString: toString() メソッドを実装します 2. @Data: クラスに注釈が付けられ、クラスのすべてのプロパティの取得および設定メソッドを提供します。さらに、equals、canEqual、hashCode、および toString メソッドが提供されます。 . @Setter: プロパティに関する注釈。プロパティの設定メソッドを提供します。 @Getter: 属性に注釈が付けられ、属性の取得メソッドを提供します @Log4j: クラスに注釈が付けられ、クラスの log という名前の属性を持つ log4j ログ オブジェクトを提供します @NoArgsConstructor: クラスに注釈が付けられ、パラメータのないコンストラクターを提供しますクラス @All
