詳解Java反射各種應(yīng)用
Java除了給我們提供在編譯期得到類(lèi)的各種信息之外,還通過(guò)反射讓我們可以在運(yùn)行期間得到類(lèi)的各種信息。通過(guò)反射獲取類(lèi)的信息,得到類(lèi)的信息之后,就可以獲取以下相關(guān)內(nèi)容:
- Class對(duì)象
- 構(gòu)造器
- 變量
- 方法
- 私有變量與私有方法
- 注解
- 泛型
- 數(shù)組
本文也將從上面幾個(gè)方面來(lái)介紹Java反射。本文涉及的所有代碼均在反射代碼
首先放出一個(gè)Java類(lèi)作為反射的研究對(duì)象,類(lèi)的內(nèi)容如下:
public abstract class FatherObject implements Runnable{
public void doSomething(){
System.out.println("做事情......");
}
}
public class ExampleObject extends FatherObject{
public int age = 30;
public String name = "byhieg";
private Integer score = 60;
public void printName(){
System.out.println(name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public ExampleObject(){
}
public ExampleObject(String name){
}
public ExampleObject(int age,Integer score){
}
@Override
public void doSomething() {
super.doSomething();
}
@Override
public void run() {
System.out.println("run......");
}
}
Class對(duì)象
我們應(yīng)用會(huì)用到反射這個(gè)知識(shí)點(diǎn),肯定是想要在運(yùn)行時(shí)得到類(lèi)的信息,根據(jù)類(lèi)的那些信息去做一些特定的操作。那么,首先無(wú)疑就是得到類(lèi)的信息,在JDK中提供了Class對(duì)象來(lái)保存類(lèi)的信息。所以,反射的第一步就是得到Class對(duì)象。在JDK中提供了兩種方式得到Class對(duì)象。
第一種,如果編寫(xiě)代碼的時(shí)候,就知道Class的名字,可以直接用如下方式得到Class對(duì)象:
Class exampleObjectClass = ExampleObject.class;
第二種,如果在編寫(xiě)代碼的時(shí)候,不知道類(lèi)的名字,但是在運(yùn)行時(shí)的時(shí)候,可以得到一個(gè)類(lèi)名的字符串,可以用如下的方式獲取Class對(duì)象:
Class exampleObjectClass = Class.forName("cn.byhieg.reflectiontutorial.ExampleObject");
注意,此方法需要有2個(gè)條件,第一,forName中的字符串必須是全限定名,第二,這個(gè)Class類(lèi)必須在classpath的路徑下面,因?yàn)樵摲椒〞?huì)拋出ClassNotFoundException的異常。
獲取到這個(gè)Class對(duì)象之后,就可以得到類(lèi)的各種信息,開(kāi)頭已經(jīng)提及了一些信息,下面,說(shuō)幾個(gè)沒(méi)提到的類(lèi)的信息。
得到類(lèi)的名字
類(lèi)的名字有兩種方式得到,一種是getName(),一種是getSimpleName()。第一種得到的是全限定名,第二種得到的是這個(gè)類(lèi)的名字,不帶包名??聪旅娴睦樱篊lass對(duì)象,已經(jīng)通過(guò)上面的代碼得到了。
String fullClassName = exampleObjectClass.getName(); String simpleClassName = exampleObjectClass.getSimpleName(); System.out.println(fullClassName); System.out.println(simpleClassName);
結(jié)果如下:
cn.byhieg.reflectiontutorial.ExampleObject ExampleObject
得到類(lèi)的包名、父類(lèi)和實(shí)現(xiàn)的接口
類(lèi)的包名和父類(lèi),可以通過(guò)如下代碼得到。
//得到包信息 Package aPackage = exampleObjectClass.getPackage(); System.out.println(aPackage); //得到父類(lèi) Class superClass = exampleObjectClass.getSuperclass(); System.out.println(superClass.getSimpleName());
結(jié)果如下:
package cn.byhieg.reflectiontutorial FatherObject
很顯然,得到父類(lèi)的返回值也是一個(gè)Class對(duì)象,那么可以利用這個(gè)對(duì)象得到父類(lèi)的一些信息,比如判斷父類(lèi)是不是抽象類(lèi)
System.out.println("父類(lèi)是不是抽象類(lèi) " + Modifier.isAbstract(superClass.getModifiers()));
getModifiers可以得到類(lèi)的修飾符,從而得到類(lèi)的修飾符,當(dāng)然,這個(gè)getModifiers不僅僅Class對(duì)象可以調(diào)用,Method對(duì)象可以調(diào)用。
可以使用java.lang.reflect.Modifier類(lèi)中的方法來(lái)檢查修飾符的類(lèi)型:
Modifier.isAbstract(int modifiers); Modifier.isFinal(int modifiers); Modifier.isInterface(int modifiers); Modifier.isNative(int modifiers); Modifier.isPrivate(int modifiers); Modifier.isProtected(int modifiers); Modifier.isPublic(int modifiers); Modifier.isStatic(int modifiers); Modifier.isStrict(int modifiers); Modifier.isSynchronized(int modifiers); Modifier.isTransient(int modifiers); Modifier.isVolatile(int modifiers);
此外,我們還可以得到父類(lèi)實(shí)現(xiàn)的接口
//得到接口
Class[] classes = superClass.getInterfaces();
System.out.println("父類(lèi)的接口" + classes[0]);
因?yàn)镴ava類(lèi)可以實(shí)現(xiàn)很多接口,所以用的數(shù)組,但在實(shí)際使用的時(shí)候,需要先判斷數(shù)組的長(zhǎng)度。
下面,重點(diǎn)講解上述列出來(lái)的內(nèi)容。
構(gòu)造器
利用Java反射可以得到一個(gè)類(lèi)的構(gòu)造器,并根據(jù)構(gòu)造器,在運(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建一個(gè)對(duì)象。首先,Java通過(guò)以下方式獲取構(gòu)造器的實(shí)例:
//構(gòu)造器
Constructor[] constructors = exampleObjectClass.getConstructors();
for (Constructor constructor : constructors){
System.out.println(constructor.toString());
}
結(jié)果如下:
public cn.byhieg.reflectiontutorial.ExampleObject(int,java.lang.Integer) public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String) public cn.byhieg.reflectiontutorial.ExampleObject()
如果,事先知道要訪(fǎng)問(wèn)的構(gòu)造方法的參數(shù)類(lèi)型,可以利用如下方法獲取指定的構(gòu)造方法,例子如下:
Constructor constructor = exampleObjectClass.getConstructor(String.class); System.out.println(constructor.toString());
結(jié)果顯然是:
public cn.byhieg.reflectiontutorial.ExampleObject(java.lang.String)
還可以用如下方式得到另一個(gè)構(gòu)造器
Constructor constructor = exampleObjectClass.getConstructor(int.class,Integer.class); System.out.println(constructor.toString());
此外,如果我們不知道構(gòu)造器的參數(shù),只能得到所有的構(gòu)造器對(duì)象,那么可以用如下方式得到每一個(gè)構(gòu)造器對(duì)想的參數(shù):
Constructor[] constructors = exampleObjectClass.getConstructors();
for (Constructor constructor : constructors){
Class[] parameterTypes = constructor.getParameterTypes();
System.out.println("構(gòu)造器參數(shù)如下========================");
for (Class clz : parameterTypes){
System.out.println("參數(shù)類(lèi)型 " + clz.toString());
}
}
結(jié)果如下:
構(gòu)造器參數(shù)如下======================== 參數(shù)類(lèi)型 class java.lang.String 構(gòu)造器參數(shù)如下======================== 參數(shù)類(lèi)型 int 參數(shù)類(lèi)型 class java.lang.Integer
這里,可以看出無(wú)參構(gòu)造方法,是不打印出結(jié)果的?;绢?lèi)型的Class對(duì)象和引用類(lèi)型的Class對(duì)象toString()方法是不一樣的。
現(xiàn)在,可以根據(jù)構(gòu)造器的各種信息,動(dòng)態(tài)創(chuàng)建一個(gè)對(duì)象。
Object object = constructor.newInstance(1,100); System.out.println(object.toString());
這個(gè)創(chuàng)建對(duì)象的方式有2個(gè)條件,第一是通過(guò)有參構(gòu)造器創(chuàng)建的,第二,構(gòu)造器對(duì)象必須通過(guò)傳入?yún)?shù)信息的getConstructor得到。
第一個(gè)條件,對(duì)于無(wú)參構(gòu)造方法就可以創(chuàng)建的對(duì)象,不需要得到構(gòu)造器對(duì)象,直接Class對(duì)象調(diào)用newInstance()方法就直接創(chuàng)建對(duì)象。
第二個(gè)條件,構(gòu)造器對(duì)象必須通過(guò)exampleObjectClass.getConstructor(String.class);這種形式得到。如果通過(guò)getConstructors得到構(gòu)造器數(shù)組,然后調(diào)用指定的構(gòu)造器對(duì)象去創(chuàng)建對(duì)象在JDK1.8是會(huì)錯(cuò)的。但是JDK1.6是正常的。
變量
利用Java反射可以在運(yùn)行時(shí)得到一個(gè)類(lèi)的變量信息,并且可以根據(jù)上面講的方式,創(chuàng)建一個(gè)對(duì)象,設(shè)置他的變量值。首先,通過(guò)如下方法,得到所有public的變量:
Field[] fields = exampleObjectClass.getFields();
for (Field field : fields){
System.out.println("變量為: " + field.toString());
}
結(jié)果如下:
變量為: public int cn.byhieg.reflectiontutorial.ExampleObject.age 變量為: public java.lang.String cn.byhieg.reflectiontutorial.ExampleObject.name
很顯然,得到的都是public的變量,上述的private的變量score,并沒(méi)有得到。
和構(gòu)造器一樣的得到方式一樣,我們可以指定一個(gè)參數(shù)名,然后得到指定的變量:
Field field = exampleObjectClass.getField("age");
System.out.println("變量為:" + field.toString());
上述的變量的toString方法得到的名字太長(zhǎng),Java對(duì)Field類(lèi)提供了getName的方法,返回類(lèi)中寫(xiě)的變量名字,上面的代碼就可以改成field.getName()。
反射不僅提供了得到變量的方法,還提供了設(shè)置變量值的方式。通過(guò)如下方法可以對(duì)一個(gè)動(dòng)態(tài)生成的類(lèi),改變其變量值:
ExampleObject object = ((ExampleObject) constructor1.newInstance("byhieg"));
System.out.println("原先的age是 " + object.age);
field.set(object,10);
System.out.println("更改之后的age是" + object.age);
結(jié)果如下:
原先的age是 30 更改之后的age是10
根據(jù)上面的代碼,得到名字為age的Field對(duì)象,然后調(diào)用該對(duì)象的set方法,傳入一個(gè)對(duì)象與要更改的值,就可以改變?cè)搶?duì)象的值了。注意,此方法不僅僅對(duì)成員變量有用,對(duì)靜態(tài)變量也可以。當(dāng)然,如果是靜態(tài)變量,傳入null,不用傳對(duì)象,也是可以的。
方法
Java反射給我們除了給我們提供類(lèi)的變量信息之外,當(dāng)然也給我們提供了方法的信息,反射可以讓我們得到方法名,方法的參數(shù),方法的返回類(lèi)型,以及調(diào)用方法等功能。
首先,通過(guò)如下代碼得到方法:
//輸出類(lèi)的public方法
Method[] methods = exampleObjectClass.getMethods();
for (Method method : methods){
System.out.println("method = "+ method.getName());
}
和獲取變量一樣似曾相識(shí)的代碼,這里直接調(diào)用了getName,來(lái)得到類(lèi)中寫(xiě)的方法名。寫(xiě)到這里,大家應(yīng)該自然想到,Java同樣提供了根據(jù)參數(shù),得到具體的方法。
Method method = exampleObjectClass.getMethod("setAge",int.class);
System.out.println(method.getName());
這里與得到變量不同的是,getMethod方法還需要傳入?yún)?shù)的類(lèi)型信息,反射提供獲取方法參數(shù)以及返回類(lèi)型的方法,得到方法參數(shù)的例子如下:
Method method = exampleObjectClass.getMethod("setAge",int.class);
System.out.println(method.getName());
for (Class clz : method.getParameterTypes()){
System.out.println("方法的參數(shù)" + clz.getName());
}
結(jié)果如下:
setAge 方法的參數(shù)int
得到方法返回類(lèi)型的例子如下:
System.out.println(method.getReturnType().getName());
結(jié)果如下:
void
此外,Java反射支持通過(guò)invoke調(diào)用得到的方法。例子如下:
method.invoke(exampleObjectClass.newInstance(),1);
invoke第一個(gè)參數(shù)是這個(gè)對(duì)象,第二個(gè)參數(shù)是變長(zhǎng)數(shù)組,傳入該方法的參數(shù)。和Field對(duì)象同樣,對(duì)于靜態(tài)方法同樣,可以傳入null,調(diào)用靜態(tài)方法。
私有變量與私有方法
上面的方法只能得到public方法和變量,無(wú)法得到非public修飾的方法和變量,Java提供了額外的方法來(lái)得到非public變量與方法。即通過(guò)getDeclaredFields與getDeclaredMethods方法得到私有的變量與方法,同樣也支持用getDeclaredField(變量名)與getDeclaredMethod(方法名)的形式得到指定的變量名與方法名。但是這樣得到的Field對(duì)象與Method對(duì)象無(wú)法直接運(yùn)用,必須讓這些對(duì)象調(diào)用setAccessible(true),才能正常運(yùn)用。之后的方式就可上面講的一樣了。
注解
先寫(xiě)一個(gè)包含注解的類(lèi):
@MyAnnotation(name="byhieg",value = "hello world")
public class AnnotationObject {
@MyAnnotation(name="field",value = "變量")
public String field;
@MyAnnotation(name="method",value = "方法")
public void doSomeThing(){
System.out.println("做一些事情");
}
public void doOtherThing(@MyAnnotation(name="param",value = "參數(shù)") String param){
}
}
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name();
public String value();
}
Java給我們提供了在運(yùn)行時(shí)獲取類(lèi)的注解信息,可以得到類(lèi)注解,方法注解,參數(shù)注解,變量注解。
與上面獲取方式一樣,Java提供了2種獲取方式,一種是獲取全部的注解,返回一個(gè)數(shù)組,第二種是指定得到指定的注解。
我們以一個(gè)類(lèi)注解為例,講解以下這兩種獲取方式。
Class clz = AnnotationObject.class; Annotation[] annotations = clz.getAnnotations(); Annotation annotation = clz.getAnnotation(AnnotationObject.class);
然后,就可以根據(jù)得到的注解進(jìn)行后續(xù)的處理,下面是一個(gè)處理的例子:
for (Annotation annotation : annotations){
if (annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation)annotation;
System.out.println("name: " + myAnnotation.name());
System.out.println("value:" + myAnnotation.value());
}
}
上面的類(lèi)注解使用Class對(duì)象調(diào)用getAnnotations得到的,方法注解和變量注解是一樣的,分別用method對(duì)象與field對(duì)象調(diào)用getDeclaredAnnotations得到注解,沒(méi)什么多說(shuō)的。例子看反射代碼
參數(shù)注解是比較麻煩的一項(xiàng),獲取方式比較得到,第一步,先取得method對(duì)象,調(diào)用getParameterAnnotations,但是這個(gè)返回值是一個(gè)二維數(shù)組,因?yàn)閙ethod對(duì)象有很多參數(shù),每個(gè)參數(shù)有可能有很多注解。例子如下:
Method method1 = clz.getMethod("doOtherThing",String.class);
Annotation[][] annotationInParam = method1.getParameterAnnotations();
Class[] params = method1.getParameterTypes();
int i = 0;
for (Annotation[] annotations: annotationInParam){
Class para = params[i++];
for (Annotation annotation : annotations){
if(annotation instanceof MyAnnotation){
MyAnnotation myAnnotation = (MyAnnotation) annotation;
System.out.println("param: " + para.getName());
System.out.println("name : " + myAnnotation.name());
System.out.println("value :" + myAnnotation.value());
}
}
}
泛型
因?yàn)镴ava泛型是通過(guò)擦除來(lái)實(shí)現(xiàn)的,很難直接得到泛型具體的參數(shù)化類(lèi)型的信息,但是我們可以通過(guò)一種間接的形式利用反射得到泛型信息。比如下面這個(gè)類(lèi):
public class GenericObject {
public List<String> lists;
public List<String> getLists() {
return lists;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
}
如果一個(gè)方法返回一個(gè)泛型類(lèi),我們可以通過(guò)method對(duì)象去調(diào)用getGenericReturnType來(lái)得到這個(gè)泛型類(lèi)具體的參數(shù)化類(lèi)型是什么??聪旅娴拇a:
Class clz = GenericObject.class;
Method method = clz.getMethod("getLists");
Type genericType = method.getGenericReturnType();
if(genericType instanceof ParameterizedType){
ParameterizedType parameterizedType = ((ParameterizedType) genericType);
Type[] types = parameterizedType.getActualTypeArguments();
for (Type type : types){
Class actualClz = ((Class) type);
System.out.println("參數(shù)化類(lèi)型為 : " + actualClz);
}
}
結(jié)果如下:
參數(shù)化類(lèi)型為 : class java.lang.String
步驟有點(diǎn)繁瑣,下面一步步解釋?zhuān)?/p>
- 反射得到返回類(lèi)型為泛型類(lèi)的方法
- 調(diào)用getGenericReturnType得到方法返回類(lèi)型中的參數(shù)化類(lèi)型
- 判斷該type對(duì)象能不能向下轉(zhuǎn)型為ParameterizedType
- 轉(zhuǎn)型成功,調(diào)用getActualTypeArguments得到參數(shù)化類(lèi)型的數(shù)組,因?yàn)橛械姆盒皖?lèi),不只只有一個(gè)參數(shù)化類(lèi)型如Map
- 取出數(shù)組中的每一個(gè)的值,轉(zhuǎn)型為Class對(duì)象輸出。
看結(jié)果確實(shí)得到了泛型的具體的信息。
如果沒(méi)有一個(gè)方法返回泛型類(lèi)型,那么我們也可以通過(guò)方法的參數(shù)為泛型類(lèi),來(lái)得到泛型的參數(shù)化類(lèi)型,如上面類(lèi)中的setLists方法。例子如下:
Method setMethod = clz.getMethod("setLists", List.class);
Type[] genericParameterTypes = setMethod.getGenericParameterTypes();
for (Type genericParameterType: genericParameterTypes){
System.out.println("GenericParameterTypes為 : " + genericParameterType.getTypeName());
if(genericParameterType instanceof ParameterizedType){
ParameterizedType parameterizedType = ((ParameterizedType) genericParameterType);
System.out.println("ParameterizedType為 :" + parameterizedType.getTypeName());
Type types[] = parameterizedType.getActualTypeArguments();
for (Type type : types){
System.out.println("參數(shù)化類(lèi)型為 : " + ((Class) type).getName());
}
}
}
執(zhí)行的結(jié)果如下:
GenericParameterTypes為 : java.util.List<java.lang.String> ParameterizedType為 :java.util.List<java.lang.String> 參數(shù)化類(lèi)型為 : java.lang.String
因?yàn)榉椒ǖ膮?shù)為泛型類(lèi)型的可能不止一個(gè),所以通過(guò)getGenericParameterTypes得到是一個(gè)數(shù)組,我們需要確定每一個(gè)元素,是否是具有參數(shù)化類(lèi)型。后續(xù)的步驟與上面類(lèi)似,就不多說(shuō)了。
如果連方法參數(shù)都不帶泛型類(lèi),那么只剩下最后一種情況,通過(guò)變量類(lèi)型,即用Field類(lèi)。例子如下:
Field field = clz.getField("lists");
Type type = field.getGenericType();
if (type instanceof ParameterizedType){
ParameterizedType parameterizedType = ((ParameterizedType) type);
Type [] types = parameterizedType.getActualTypeArguments();
for (Type type1 : types) {
System.out.println("參數(shù)化類(lèi)型 : " + ((Class) type1).getTypeName());
}
}
原理和上面的一樣,只不過(guò)Type對(duì)象是通過(guò)field.getGenericType(),剩下的操作類(lèi)似就不多說(shuō)了。
關(guān)于通過(guò)反射獲取泛型的參數(shù)化類(lèi)型的信息的介紹就到此為止。
數(shù)組
Java反射可以對(duì)數(shù)組進(jìn)行操作,包括創(chuàng)建一個(gè)數(shù)組,訪(fǎng)問(wèn)數(shù)組中的值,以及得到一個(gè)數(shù)組的Class對(duì)象。
下面,先說(shuō)簡(jiǎn)單的,創(chuàng)建數(shù)組以及訪(fǎng)問(wèn)數(shù)組中的值:在反射中使用Array這個(gè)類(lèi),是reflect包下面的。
//創(chuàng)建一個(gè)int類(lèi)型的數(shù)組,長(zhǎng)度為3
int[] intArray = (int[])Array.newInstance(int.class,3);
//通過(guò)反射的形式,給數(shù)組賦值
for (int i = 0 ;i < intArray.length;i++){
Array.set(intArray,i,i + 2);
}
//通過(guò)反射的形式,得到數(shù)組中的值
for (int i = 0 ; i < intArray.length;i++){
System.out.println(Array.get(intArray,i));
}
上述就是創(chuàng)建數(shù)組,訪(fǎng)問(wèn)數(shù)組中的值利用反射方式。
對(duì)于得到一個(gè)數(shù)組的Class對(duì)象,簡(jiǎn)單的可以用int[].class,或者利用Class.forName的形式得到,寫(xiě)法比較奇怪:
Class clz = Class.forName("[I");
System.out.println(clz.getTypeName());
結(jié)果為:
int[]
這個(gè)forName中的字符串,[ 表示是數(shù)組,I 表示是int,float就是 F,double就是 D 等等,如果要得到一個(gè)普通對(duì)象的數(shù)組,則用下面的形式:
Class stringClz = Class.forName("[Ljava.lang.String;");
[ 表示是數(shù)組, L 的右邊是類(lèi)名,類(lèi)型的右邊是一個(gè);;
這種方式獲取數(shù)組的Class對(duì)象實(shí)在是太繁瑣了。
在得到數(shù)組的Class對(duì)象之后,就可以調(diào)用他的一些獨(dú)特的方法,比如調(diào)用getComponentType來(lái)得到數(shù)組成員的類(lèi)型信息,如int數(shù)組就是成員類(lèi)型就是int。
System.out.println(clz.getComponentType().getTypeName());
結(jié)果為int
總結(jié)
這次,關(guān)于反射的各種應(yīng)用就到此為止,后續(xù)可能會(huì)有深入的知識(shí)講解。具體的代碼可以去看反射代碼
在src包里面是各種類(lèi),在test類(lèi)里是對(duì)這些類(lèi)的訪(fǎng)問(wèn)。
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- java中的反射應(yīng)用實(shí)現(xiàn)
- 在實(shí)踐中了解Java反射機(jī)制應(yīng)用
- Java反射在實(shí)際工作中的應(yīng)用筆記
- 淺談java反射和自定義注解的綜合應(yīng)用實(shí)例
- Java學(xué)習(xí)之反射機(jī)制及應(yīng)用場(chǎng)景介紹
- 詳解Java編程中的反射在Android開(kāi)發(fā)中的應(yīng)用
- 應(yīng)用Java泛型和反射導(dǎo)出CSV文件的方法
- Java反射學(xué)習(xí) getClass()函數(shù)應(yīng)用
- java反射應(yīng)用詳細(xì)介紹
- 詳解Java 反射和反射的應(yīng)用場(chǎng)景
相關(guān)文章
SpringBoot ThreadLocal實(shí)現(xiàn)公共字段自動(dòng)填充案例講解
每一次在Controller層中封裝改動(dòng)數(shù)據(jù)的方法時(shí)都要重新設(shè)置一些共性字段,顯得十分冗余。為了解決此問(wèn)題也是在項(xiàng)目中第一次利用到線(xiàn)程,總的來(lái)說(shuō)還是讓我眼前一亮,也開(kāi)闊了視野,對(duì)以后的開(kāi)發(fā)具有深遠(yuǎn)的意義2022-10-10
Java 實(shí)現(xiàn)萬(wàn)年歷總結(jié)
這篇文章主要介紹了Java 萬(wàn)年歷實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2016-09-09
解析Java的Spring框架的BeanPostProcessor發(fā)布處理器
這篇文章主要介紹了Java的Spring框架的BeanPostProcessor發(fā)布處理器,Spring是Java的SSH三大web開(kāi)發(fā)框架之一,需要的朋友可以參考下2015-12-12
springboot使用Mybatis-plus分頁(yè)插件的案例詳解
這篇文章主要介紹了springboot使用Mybatis-plus分頁(yè)插件的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
SpringBoot 返回Json實(shí)體類(lèi)屬性大小寫(xiě)的解決
這篇文章主要介紹了SpringBoot 返回Json實(shí)體類(lèi)屬性大小寫(xiě)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
輕松學(xué)會(huì)使用JavaMail?API發(fā)送郵件
想要輕松學(xué)會(huì)使用JavaMail?API發(fā)送郵件嗎?本指南將帶你快速掌握這一技能,讓你能夠輕松發(fā)送電子郵件,無(wú)論是個(gè)人還是工作需求,跟著我們的步驟,很快你就可以在Java應(yīng)用程序中自如地處理郵件通信了!2023-12-12

