日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java反射 interface_Java反射

發布時間:2023/12/14 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java反射 interface_Java反射 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 介紹

反射是一種能夠在程序運行時動態訪問、修改某個類中任意屬性和方法的機制。

具體:

對于任意一個類,都能夠知道這個類的所有屬性和方法

對于任意一個對象,都能夠調用它的任意一個方法和屬性

在運行時,當加載完類之后,JVM在堆內存中會自動產生一個Class類型的對象,這個對象包含了完整的類的結構信息

這個Class對象就像一面鏡子,透過這個鏡子看到類的結構

那么,如何得到這個Class對象呢?以下可否

Class c = new Class();

答案是不行的,因為Class的構造函數定義為私有的,只有JVM可以訪問

privateClass(ClassLoader loader) {

classLoader=loader;

}

Class對象獲取的三種方式

Class c1 = Code.class;

Class c2=code1.getClass();

Class c3= Class.forName("com.trigl.reflect.Code");

舉例

public classTestStudent {public static void main(String[] args) throwsClassNotFoundException {

Student student= new Student(1, "Jack");

Class class1=student.getClass();

Class class2= Student.class;

Class class3= Class.forName("com.example.refs.Student");

System.out.println(class1);

System.out.println(class2);

System.out.println(class3);

}

}

輸出

classcom.example.refs.Studentclasscom.example.refs.Studentclass com.example.refs.Student

2. Java反射相關操作

本文以Student類為例:

接口

packagecom.example.refs;public interfaceInterFace {voidread();

}

packagecom.example.refs;public class Student implementsInterFace{private intid;publicString name;publicStudent() {}public Student(intid, String name) {this.id =id;this.name =name;

}public void setId(intid) {this.id =id;

}private intgetId() {returnid;

}

@Overridepublic voidread() {}

}

以下具體介紹下具體的用法

2.1 類名稱、包名

public classClassName {public static voidmain(String[] args) {

Class> class2 = Student.class;

System.out.println("getSimpleName:" +class2.getSimpleName());

System.out.println("getName:" +class2.getName());

System.out.println("getPackage:" +class2.getPackage());

}

}

輸出

getSimpleName:Student

getName:com.example.refs.Student

getPackage:package: com.example.refs

2.2 方法

public Method getDeclaredMethod(String name, Class>...parameterTypes) // 得到本類所有的方法(public/private/proteceted...)public Method getMethod(String name, Class>...parameterTypes) //得到該類所有的public方法,包括父類

舉例

public classMethodTest {public static voidmain(String[] args) {

Class> class1 = Student.class;

Method[] methods=class1.getMethods();

Method[] declaredMethods=class1.getDeclaredMethods();for(Method method : methods) {

System.out.println("getMethods: " +method);

}

System.out.println();for(Method method : declaredMethods) {

System.out.println("getDeclaredMethods: " +method);

}

}

}

結果

getMethods: public void com.example.refs.Student.read()

getMethods: public void com.example.refs.Student.setId(int)

getMethods: public final void java.lang.Object.wait() throws java.lang.InterruptedException

getMethods: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

getMethods: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

getMethods: public boolean java.lang.Object.equals(java.lang.Object)

getMethods: public java.lang.String java.lang.Object.toString()

getMethods: public native int java.lang.Object.hashCode()

getMethods: public final native java.lang.Class java.lang.Object.getClass()

getMethods: public final native void java.lang.Object.notify()

getMethods: public final native void java.lang.Object.notifyAll()

getDeclaredMethods: public void com.example.refs.Student.read()

getDeclaredMethods: private int com.example.refs.Student.getId()

getDeclaredMethods: public void com.example.refs.Student.setId(int)

指定方法

public classMethodChangeVal {public static void main(String[] args) throwsIllegalAccessException, InstantiationException,

NoSuchMethodException, InvocationTargetException {

Class clazz= Student.class;

Object obj=clazz.newInstance();

Method methodGet= clazz.getDeclaredMethod("getId");

Method methodSet= clazz.getDeclaredMethod("setId", int.class);

methodSet.invoke(obj,123);

System.out.println(methodGet.invoke(obj));

}

}

異常

Exception in thread "main" java.lang.IllegalAccessException: Class

com.example.refs.MethodChangeVal can not access a member of class

com.example.refs.Student with modifiers "private"

原因:setId為私有方法,利用反射時會進行安全檢查,用setAccessible(true)不進行安全檢查,可以直接對調用私有方法、修改私有變量

public classMethodChangeVal {public static void main(String[] args) throwsIllegalAccessException, InstantiationException,

NoSuchMethodException, InvocationTargetException {

Class clazz= Student.class;

Object obj=clazz.newInstance();

Method methodGet= clazz.getDeclaredMethod("getId");

Method methodSet= clazz.getDeclaredMethod("setId", int.class);

methodGet.setAccessible(true);

methodSet.invoke(obj,123);

System.out.println(methodGet.invoke(obj));

}

}

2.3 構造函數

public Constructor getDeclaredConstructor(Class>... parameterTypes)public Constructor getConstructor(Class>... parameterTypes)

Constructor>[] allConstructors = class1.getDeclaredConstructors();//獲取class對象的所有聲明構造函數

Constructor>[] publicConstructors = class1.getConstructors();//獲取class對象public構造函數

Constructor> constructor = class1.getDeclaredConstructor(String.class);//獲取指定聲明構造函數

Constructor publicConstructor = class1.getConstructor(String.class);//獲取指定聲明的public構造函數

舉例

public classConstuctorTest {public static voidmain(String[] args) {

Class class2= Student.class;

Constructor>[] constructors =class2.getConstructors();for (Constructor>constructor : constructors) {

System.out.println(constructor+ ", Name:" +constructor.getName());

}

}

}

結果

publiccom.example.refs.Student(), Name:com.example.refs.Studentpublic com.example.refs.Student(int,java.lang.String), Name:com.example.refs.Student

2.4 成員變量

getDeclaredFields()獲得某個類的所有申明的字段,即包括public、private和proteced,但是不包括父類的申明字段。

getFields()獲得某個類的所有的公共(public)的字段,包括父類。

舉例

public classFieldTest {public static voidmain(String[] args) {

Class> aClass = Student.class;

Field[] declardFields=aClass.getDeclaredFields();

Field[] fields=aClass.getFields();for(Field field : declardFields) {

System.out.println("declaredField: " +field);

}

System.out.println();for(Field field : fields) {

System.out.println("field: " +field);

}

}

}

結果

declaredField: private intcom.example.refs.Student.id

declaredField:publicjava.lang.String com.example.refs.Student.name

field:public java.lang.String com.example.refs.Student.name

2.5 修飾符

舉例

public classModifierTest {public static voidmain(String args[]) {

Class aClass= Student.class;int modifier =aClass.getModifiers();

System.out.println("modifier:" +modifier);

System.out.println(String.format("isAbstract: %s", Modifier.isAbstract(modifier)));

System.out.println(String.format("isPublic: %s", Modifier.isPublic(modifier)));

System.out.println(String.format("isStatic: %s", Modifier.isStatic(modifier)));

System.out.println(String.format("isFinal: %s", Modifier.isFinal(modifier)));

System.out.println(String.format("isSynchronized: %s", Modifier.isSynchronized(modifier)));

}

}

結果

modifier:1isAbstract:falseisPublic:trueisStatic:falseisFinal:falseisSynchronized:false

2.6 父類

public classGetParent {public static voidmain(String[] args) {

Class class2= Student.class;

System.out.println(class2.getSuperclass());

}

}

結果

class java.lang.Object

2.7 接口

public classInterfaceTest {public static voidmain(String[] args) {

Class> clazz = Student.class;

Class>[] inters =clazz.getInterfaces();for(Class>classIn : inters) {

System.out.println(classIn);

}

}

}

輸出

interface com.example.refs.InterFace

2.8 創建對象實例

舉例用2種方法創建

public classNewInstanceTest {public static void main(String[] args) throwsIllegalAccessException, InstantiationException,

NoSuchMethodException, InvocationTargetException {

Class clazz= Student.class;

Object obj=clazz.newInstance();

Constructor> constructor =clazz.getDeclaredConstructor();

Object obj2=constructor.newInstance();

Constructor> constructor2 = clazz.getDeclaredConstructor(int.class, String.class);

Object obj3= constructor2.newInstance(1, "HanMeimei");

System.out.println(obj);

System.out.println(obj2);

System.out.println(obj3);

}

}

結果

2.9 注解

自定義一個注解

@Retention(RetentionPolicy.RUNTIME)

@interfaceMyAnnotation {publicString name();public String value();

注:RetentionPolicy.RUNTIME 這個表示運行期注解,這樣在反射的時候才能取到

舉例

public classAnnotationTest {

@MyAnnotation(name="someName", value = "Hello World")public voiddoSomething() {

}

@Deprecatedpublic voiddelFunc() {

System.out.println("Hello");

}public static void main(String[] args) throwsNoSuchMethodException {

Class clazz= AnnotationTest.class;

Method method= clazz.getMethod("doSomething");

Annotation[] declaredAnnotations=method.getDeclaredAnnotations();for(Annotation annotation : declaredAnnotations) {if (annotation instanceofMyAnnotation) {

MyAnnotation myAnnotation=(MyAnnotation)annotation;

System.out.println("name:" +myAnnotation.name());

System.out.println("value:" +myAnnotation.value());

}else{

System.out.println(annotation);

}

}

}

}

結果

name:someName

value:Hello World

2.10 泛型

參數類型、返回值類型舉例

public classGenericTest {public void test01(Map map, Listlist) {

System.out.println("test01");

}public Maptest02() {

System.out.println("test02");return null;

}public static void main(String[] args) throwsNoSuchMethodException {

Method method= GenericTest.class.getMethod("test01", Map.class, List.class);

Type[] types=method.getGenericParameterTypes();for(Type type : types) {

System.out.println("#:" +type);if (type instanceofParameterizedType) {

Type[] genericType=((ParameterizedType)type).getActualTypeArguments();for(Type ontGenericType : genericType) {

System.out.println("泛型類型:" +ontGenericType);

}

}

}

Method method2= GenericTest.class.getMethod("test02");

Type returnType=method2.getGenericReturnType();

System.out.println("\nReturntype" +returnType);if (returnType instanceofParameterizedType) {

Type[] genericTypes=((ParameterizedType)returnType).getActualTypeArguments();for(Type type : genericTypes) {

System.out.println("返回值,泛型類型:" +type);

}

}

}

}

結果

#:java.util.Map

泛型類型:class java.lang.String

泛型類型:class com.example.refs.Student

#:java.util.List

泛型類型:class com.example.refs.Student

Returntypejava.util.Map

返回值,泛型類型:class java.lang.Integer

返回值,泛型類型:class com.example.refs.Student

2.11 數組

public classArrayTest {public static voidmain(String[] args) {int[] intArray = (int[])Array.newInstance(int.class, 3);

Array.set(intArray,0, 123);

Array.set(intArray,1, 124);

Array.set(intArray,2, 125);for (int i = 0; i < Array.getLength(intArray); ++i) {

System.out.println(String.format("array[%s]:%s", i, Array.get(intArray, i)));

}

Class aClass=intArray.getClass();

System.out.println("intArray是否是數組類型:" +aClass.isArray());

System.out.println("intArray成員類型:" +aClass.getComponentType());

}

}

結果

array[0]:123

array[1]:124

array[2]:125

intArray是否是數組類型:true

intArray成員類型:int

3. 分析

3.1 使用場景

操作因訪問權限限制的屬性和方法

實現自定義注解

動態加載第三方jar包

按需加載類,節省編譯和初始化APK的時間

3.2 優缺點

優點:靈活、自由度高:不受類的訪問權限限制

缺點

性能問題:通過反射訪問、修改類的屬性和方法時會遠慢于直接操作,但性能問題的嚴重程度取決于在程序中是如何使用反射的。如果使用得很少,不是很頻繁,性能將不是問題

安全性問題:反射可以隨意訪問和修改類的所有狀態和行為,破壞了類的封裝性,如果不熟悉被反射類的實現原理,隨意修改可能導致潛在的邏輯問題

兼容性問題:因為反射會涉及到直接訪問類的方法名和實例名,不同版本的API如果有變動,反射時找不到對應的屬性和方法時會報異常

3.3 說明

通過反射訪問方法比實例慢很多

有用到反射的類不能被混淆

反射存在性能問題,但使用不頻繁、按需使用時,對程序性能影響并不大

反射存在安全性問題,因為可以隨意修改類的所有狀態和行為(包括private方法和實例)

使用反射訪問Android的API時需要注意因為不同API版本導致的兼容性問題

3.4 性能對比

不使用反射、啟用安全檢查、啟用安全檢查進行對比

public classTestReflect {

@Testpublic voidtestNoneReflect() {

Student oneStudent= new Student(1, "HanMeimei");long start =System.currentTimeMillis();for (long i = 0; i < Integer.MAX_VALUE; ++i) { oneStudent.setId(1); }long count = System.currentTimeMillis() -start;

System.out.println("沒有反射, 共消耗 毫秒");

}

@Testpublic void testNotAccess() throwsClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException,

InvocationTargetException {

Student oneStudent= new Student(1, "HanMeimei");

Method method= Class.forName("com.example.refs.Student").getMethod("setId", int.class);long start =System.currentTimeMillis();for (long i = 0; i < Integer.MAX_VALUE; ++i) { method.invoke(oneStudent, 1); }long count = System.currentTimeMillis() -start;

System.out.println("啟用安全檢查, 共消耗 毫秒");

}

@Testpublic void testUseAccess() throwsClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

Student oneStudent= new Student(1, "HanMeimei");

Method method= Class.forName("com.example.refs.Student").getMethod("setId", int.class);

method.setAccessible(true);long start =System.currentTimeMillis();for (long i = 0; i < Integer.MAX_VALUE; ++i) { method.invoke(oneStudent, 1); }long count = System.currentTimeMillis() -start;

System.out.println("取消安全檢查, 共消耗 毫秒");

}

}

結果對比

差異

耗時(ms)

沒用反射

952

取消安全檢查

4283

啟用安全檢查

14892

原文:http://www.cnblogs.com/kaituorensheng/p/7398069.html

總結

以上是生活随笔為你收集整理的java反射 interface_Java反射的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。