学习JavaEE的日子 Day39 注解,反射

Day39

注解

1.什么是注解

理解:给程序员和程序解释代码信息

2.注解与注释的区别

注释:对程序员解释代码信息

注解:对程序和程序员解释代码信息

3.注解的所用

可以作用于包、类、方法、属性上,给他们添加额外的信息,可以被其他程序(编译器)读取

4.注解的格式

注解是以“@注释名”在代码中存在的,还可以添加一些参数

例如:@SuppressWarnings(value=“unchecked”)

5.注解的应用

可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制实现对这些数据的访问

6.内置注解

理解:Java给我们提供个注解

*@Overrlde*:表示该方法是重写父类的方法

*@Deprecated*:表示该方法已过时

*@SuppressWarnings*:镇压警告,定义在java.lang.SuppressWarnings中用来抑制编译时的警告信息,与前两个注释有所不同.你需要添加参数才能正确使用。(镇压报小黄线的地方)

@SuppressWarnings(“all”)抑制所有类型的警告信息

@SuppressWarnings(“unchecked”)抑制单类型的警告信息

@SuppressWarnings(value={“unchecked”,“deprecation”})抑制多类型的警告信息

public class Test01 {//@Override表示该方法是重写父类的方法@Overridepublic String toString() {return super.toString();}//@Deprecated表示该方法已过时@Deprecatedpublic void method01(){}//@SuppressWarnings表示镇压警告的注解@SuppressWarnings("all")public void method02(){ArrayList list = new ArrayList();list.add(100);list.add(123.123);list.add("用良心做教育");}}

7.元注解

元注解的作用:负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明

(@Target,@Retention,@Documented,@Inherited )

*@Target*:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

  • ElementType.TYPE 类上
  • ElementType.FIELD 属性上
  • ElementType.METHOD 方法上
  • ElementType.PARAMETER 参数上
  • ElementType.LOCAL_VARIABLE 局部变量上
  • ElementType.TYPE_PARAMETER 泛型上

*@**Retention*:表示需要要在什么级别保存该注择信息,用于描述注解的生命周期

SOURCE:注解只作用在源码阶段,生成的字节码文件中不存在

CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段不存在,默认值

RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段

(SOURCE < CLASS < *RUNTIME*)

@Document:说明该注解将被包含在javadoc中

@lnherited:说明子类可以继承父类中的该注解

8.自定义注解

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

分析:

@interface用来声明一个注解,格式:public @interface注解名{定义内容}

其中的每一个方法实际上是声明了一个配置参数.

方法的名称就是参数的名称.

返回值类型就是参数的类型(返回值只能是基本类型、Class、String、enum)

可以通过default来声明参数的默认值

如果只有一个参数成员,一般参数名为value()

注解元素必須要有值,我们定义注解元素时,经常使用空字符串.0作为默认值

@MyAnnotaction
public class Test01<@MyAnnotaction T> {public static void main(String[] args) {}@MyAnnotactionString attr;@MyAnnotactionpublic static void method(@MyAnnotaction String str){@MyAnnotactionint i = 100;System.out.println(i);}
}

自定义注解类

//@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.LOCAL_VARIABLE,ElementType.TYPE_PARAMETER})
//@Target({ElementType.TYPE,ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.LOCAL_VARIABLE,ElementType.TYPE_PARAMETER})
@Target({TYPE,FIELD,METHOD,PARAMETER,LOCAL_VARIABLE,TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotaction {
}

注意:

当注解中只有"一个属性",并且属性名是"value",使用注解时,可以省略value属性名:public String value(); @Anno2(“123”)

反射

1.Java的反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

前言:

使用到一个类,JVM会将该类的class文件加载到方法区(类加载机制),同时会在堆内存中创建该类的class对象,class对象的作为class文件的访问入口

理解:

反射实际上就是获取class对象,通过class对象访问class文件中的内容

访问内容:属性;构造方法;普通方法(成员方法、静态方法、抽象方法…);方法上的参数;方法上的返回值;数组

注意:对于反射来说,一个类就是透明的,没有穿衣服的

2.关键点-获取Class文件对象

注意:

该类的class文件只在一次到方法区中,该类的class对象在程序中是唯一的。所以不管使用那种方式获取class对象都是同一个

public class Test01 {public static void main(String[] args) throws ClassNotFoundException {//获取class对象方式1Class<? extends Student> clazz1 = Student.class;//获取class对象方式2Student stu = new Student();Class<? extends Student> clazz2 = stu.getClass();//获取class方式3(一般使用这个)Class<?> clazz3 = Class.forName("com.qf.reflex01.Student");System.out.println(clazz1 == clazz2);//trueSystem.out.println(clazz1 == clazz3);//true}
}

经验:配置文件 + Class.forName() --常用

public class Test02 {public static void main(String[] args) throws IOException, ClassNotFoundException {Properties p = new Properties();p.load(Test02.class.getClassLoader().getResourceAsStream("classPath.properties"));String path = p.getProperty("path");Class<?> clazz = Class.forName(path);}
}

classPath.properties

path=com.qf.reflex01.Student

3.利用反射操作属性

Field[] getFields():返回所有成员变量对象的数组(只能拿public的)

Field[] getDeclaredFields():返回所有成员变量对象的数组,存在就能拿到

Field getField(String name):返回单个成员变量对象(只能拿public的)

Field getDeclaredField(String name):返回单个成员变量对象,存在就能拿到

注意:如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

获取成员变量并获取值和修改值

void set(Object obj, Object value):赋值

Object get(Object obj):获取值

public class Test03 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {//		Properties p = new Properties();
//		p.load(Test03.class.getClassLoader().getResourceAsStream("classPath.properties"));
//		String path = p.getProperty("path");//		Class<?> clazz = Class.forName(path);//获取本类及其父类公有的属性对象
//		Field[] fields = clazz.getFields();
//		for (Field field : fields) {
//			System.out.println(field);
//		}//获取本类所有的属性对象
//		Field[] fields = clazz.getDeclaredFields();
//		for (Field field : fields) {
//			System.out.println(field);
//		}//获取本类及其父类所有的属性对象
//		for(Class<?> c = clazz;c!=null;c=c.getSuperclass()){
//			Field[] fields = c.getDeclaredFields();
//			for (Field field : fields) {
//				System.out.println(field);
//			}
//		}//		try {
//			//获取本类指定的属性对象
//			Field field = clazz.getDeclaredField("str");
//			System.out.println(field);
//			
//			//获取属性参数值
//			int modifiers = field.getModifiers();
//			System.out.println("是否使用public修饰:" + Modifier.isPublic(modifiers));
//			System.out.println("是否使用stati修饰:" + Modifier.isStatic(modifiers));
//			System.out.println("是否使用final修饰:" + Modifier.isFinal(modifiers));
//			System.out.println("是否使用private修饰:" + Modifier.isPrivate(modifiers));
//			System.out.println("是否使用protected修饰:" + Modifier.isProtected(modifiers));
//			System.out.println("是否使用transient修饰:" + Modifier.isTransient(modifiers));
//			
//		} catch (NoSuchFieldException e) {//属性名没有配到对应的属性就报该异常
//			e.printStackTrace();
//		} catch (SecurityException e) {
//			e.printStackTrace();
//		}//通过反射设置对象里的属性
//		Student stu = new Student("巴得伟", '男', 23, "2401", "001");
//		Field field = clazz.getDeclaredField("id");
//		field.setAccessible(true);//设置修改权限
//		field.set(stu, "666");//设置stu对象里的id属性为"666"的值
//		System.out.println(stu);//通过反射工具类设置对象里的属性Student stu = new Student();ReflexUtil.setField(stu, "name", "巴得伟");ReflexUtil.setField(stu, "sex", '男');ReflexUtil.setField(stu, "age", 23);ReflexUtil.setField(stu, "classId", "2401");ReflexUtil.setField(stu, "id", "001");System.out.println(stu);}
}

Person类

package com.qf.reflex01;public class Person {private String name;private char sex;private int age;//无参构造,有参构造,set,get省略@Overridepublic String toString() {return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";}protected static final synchronized void method(){System.out.println("静态方法");}
}

Person类的子类

@MyAnnotaction(str = "aaa")
public class Student extends Person{private String classId;private String id;@MyAnnotaction(str = "bbb")public HashMap<String, Integer> map;public static final String str = "用良心做教育";//无参构造,有参构造,set,get省略 @Overridepublic String toString() {return "Student [classId=" + classId + ", id=" + id + ", toString()=" + super.toString() + "]";}public void method01(){System.out.println("无参数无返回值的方法 -- method01");}public void method02(String str, int i){System.out.println("带参数的方法 -- method02:" + str + " -- " + i);}public String method03(){return "无参数带返回值的方法 -- method03";}private String method04(String str, int i){return "带参数带返回值的方法 -- method04:" + str + " -- " + i;}@MyAnnotaction(str = "ccc")public HashMap<Character, Boolean> method05(@MyAnnotaction(str = "ddd") ArrayList<Object> list,HashMap<Number, Double> map){return null;}
}

4.利用反射操作构造方法

Constructor[] getConstructors():获得所有的构造(只能public修饰)

Constructor[] getDeclaredConstructors():获得所有的构造(包含private修饰)

Constructor getConstructor(Class… parameterTypes):获取指定构造(只能public修饰)

Constructor getDeclaredConstructor(Class… parameterTypes):获取指定构造(包含private修饰)

newInstance():获取构造方法并创建对象的方法

public class Test04 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {//		Properties p = new Properties();
//		p.load(Test04.class.getClassLoader().getResourceAsStream("classPath.properties"));
//		String path = p.getProperty("path");//		Class<?> clazz = Class.forName(path);//获取该类公有的构造方法对象
//		Constructor<?>[] constructors = clazz.getConstructors();
//		for (Constructor<?> constructor : constructors) {
//			System.out.println(constructor);
//		}//获取该类所有的构造方法对象
//		Constructor<?>[] constructors = clazz.getDeclaredConstructors();
//		for (Constructor<?> constructor : constructors) {
//			System.out.println(constructor);
//		}//获取无参构造对象
//		Constructor<?> constructor = clazz.getDeclaredConstructor();
//		//利用无参构造对象创建该类的对象
//		constructor.setAccessible(true);//设置修改权限
//		Student stu = (Student) constructor.newInstance();
//		System.out.println(stu);//利用无参构造对象创建该类的对象 -- 简化版
//		Student stu = (Student) clazz.newInstance();
//		System.out.println(stu);//获取有参构造对象
//		Constructor<?> constructor = clazz.getDeclaredConstructor(String.class,char.class,int.class,String.class,String.class);
//		//利用有参构造对象创建该类的对象
//		constructor.setAccessible(true);//设置修改权限
//		Student stu = (Student) constructor.newInstance("巴得伟",'男',23,"2401","001");
//		System.out.println(stu);//利用反射工具类去创建对象 -- 底层调用无参构造
//		Student stu = ReflexUtil.newInstance(Student.class, null, null);
//		System.out.println(stu);//利用反射工具类去创建对象 -- 底层调用有参构造Class<?>[] parameterTypes = {String.class,char.class,int.class,String.class,String.class};Object[] paremeters = {"巴得伟",'男',23,"2401","001"};Student stu = ReflexUtil.newInstance(Student.class, parameterTypes, paremeters);System.out.println(stu);}
}

5.利用反射操作方法

Method[] getMethods():返回所有成员方法对象的数组(只能拿public的)

Method[] getDeclaredMethods():返回所有成员方法对象的数组,存在就能拿到

Method getMethod(String name, Class… parameterTypes):返回单个成员方法对象(只能拿public的)

Method getDeclaredMethod(String name, Class… parameterTypes):返回单个成员方法对象,存在就能拿到

如果当前获取到的是私有的,必须要临时修改访问权限,否则无法使用

public class Test01 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException {//		Properties p = new Properties();
//		p.load(Test01.class.getClassLoader().getResourceAsStream("classPath.properties"));
//		String path = p.getProperty("path");//		Class<?> clazz = Class.forName(path);//获取本类及其父类公有的方法对象
//		Method[] methods = clazz.getMethods();
//		for (Method method : methods) {
//			System.out.println(method);
//		}//获取本类所有的方法对象
//		Method[] methods = clazz.getDeclaredMethods();
//		for (Method method : methods) {
//			System.out.println(method);
//		}//获取本类及其父类所有的方法对象
//		for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
//			Method[] methods = c.getDeclaredMethods();
//			for (Method method : methods) {
//				System.out.println(method);
//			}
//		}//获取本类公有的指定名字的方法对象
//		Method method = clazz.getMethod("setClassId", String.class);
//		System.out.println(method);//获取本类所有的指定名字的方法对象
//		Method method = clazz.getDeclaredMethod("method");
//		System.out.println(method);//利用反射工具类获取子类及其父类指定名字的方法对象
//		Method method = ReflexUtil.getMethod(clazz, "method");
//		System.out.println(method);//获取方法参数值
//		int modifiers = method.getModifiers();
//		System.out.println("是否使用public修饰:" + Modifier.isPublic(modifiers));
//		System.out.println("是否使用private修饰:" + Modifier.isPrivate(modifiers));
//		System.out.println("是否使用protected修饰:" + Modifier.isProtected(modifiers));
//		System.out.println("是否使用static修饰:" + Modifier.isStatic(modifiers));
//		System.out.println("是否使用final修饰:" + Modifier.isFinal(modifiers));
//		System.out.println("是否使用abstract修饰:" + Modifier.isAbstract(modifiers));
//		System.out.println("是否使用synchronized修饰:" + Modifier.isSynchronized(modifiers));}
}

6.利用反射操作方法

public class Test02 {public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {Properties p = new Properties();p.load(Test02.class.getClassLoader().getResourceAsStream("classPath.properties"));String path = p.getProperty("path");Class<?> clazz = Class.forName(path);//		//利用反射调用静态方法
//		Method method = ReflexUtil.getMethod(clazz, "method");
//		method.invoke(null);//静态方法不需要对象调用,就传入null
//		
//		Student stu = new Student();
//		
//		//利用反射调用成员方法 -- 无参数无返回值的方法
//		Method method01 = ReflexUtil.getMethod(clazz, "method01");
//		method01.invoke(stu);
//	
//		//利用反射调用成员方法 -- 带参数的方法
//		Method method02 = ReflexUtil.getMethod(clazz, "method02", String.class,int.class);
//		method02.invoke(stu, "用良心做教育",100);
//		
//		//利用反射调用成员方法 -- 无参数带返回值的方法
//		Method method03 = ReflexUtil.getMethod(clazz, "method03");
//		String returnVal1 = (String) method03.invoke(stu);
//		System.out.println(returnVal1);
//		
//		//利用反射调用成员方法 -- 带参数带返回值的方法
//		Method method04 = ReflexUtil.getMethod(clazz, "method04", String.class,int.class);
//		method04.setAccessible(true);//设置修改权限
//		String returnVal2 = (String) method04.invoke(stu, "用良心做教育",200);
//		System.out.println(returnVal2);//利用反射工具类 -- 调用静态方法ReflexUtil.invoke(clazz, "method", null, null);Student stu = new Student();//利用反射工具类 -- 反射调用成员方法 -- 无参数无返回值的方法ReflexUtil.invoke(stu, "method01", null, null);//利用反射工具类 -- 反射调用成员方法 -- 带参数的方法ReflexUtil.invoke(stu, "method02", new Class[]{String.class,int.class}, new Object[]{"用良心做教育",100});//利用反射工具类 -- 反射调用成员方法 -- 无参数带返回值的方法Object returnVal1 = ReflexUtil.invoke(stu, "method03", null, null);System.out.println(returnVal1);//利用反射工具类 -- 反射调用成员方法 -- 带参数带返回值的方法Object returnVal2 = ReflexUtil.invoke(stu, "method04", new Class[]{String.class,int.class}, new Object[]{"用良心做教育",100});System.out.println(returnVal2);}
}

7.利用反射操作 方法里的参数和返回值

public class Test03 {public static void main(String[] args) throws IOException, ClassNotFoundException {Properties p = new Properties();p.load(Test03.class.getClassLoader().getResourceAsStream("classPath.properties"));String path = p.getProperty("path");Class<?> clazz = Class.forName(path);//利用反射工具类获取方法对象Method method = ReflexUtil.getMethod(clazz, "method04", String.class,int.class);//获取方法的参数个数int parameterCount = method.getParameterCount();System.out.println("获取方法的参数个数:" + parameterCount);System.out.println("-----------------------------");//获取方法参数的class对象数组Class<?>[] parameterTypes = method.getParameterTypes();for (Class<?> c : parameterTypes) {System.out.println(c);}System.out.println("-----------------------------");//获取方法参数的Type对象数组//一个参数类型就是一个Type对象Type[] genericParameterTypes = method.getGenericParameterTypes();for (Type type : genericParameterTypes) {System.out.println(type);}System.out.println("-----------------------------");//获取方法参数对象数组//一个参数就是一个参数对象Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {System.out.println("获取方法的参数类型:" + parameter.getType());/*** 注意:* 		参数名不会随着编译而编译到class文件,* 		class文件描述该方法的参数名使用的是:arg0,arg1,arg2,.....*/System.out.println("获取方法的参数名:" + parameter.getName());}System.out.println("-----------------------------");//获取返回值的class对象Class<?> returnType = method.getReturnType();System.out.println("获取返回值的class对象:" + returnType);//获取返回值的Type对象Type genericReturnType = method.getGenericReturnType();System.out.println("获取返回值的Type对象:" + genericReturnType);}
}

8.利用反射操作泛型

注意:

集合中的泛型只在java文件中存在,当编译成class文件之后,就没有泛型了。

类上的泛型是获取不到的,因为不固定!!!

class A{}

public class Test04 {public static void main(String[] args) throws IOException, ClassNotFoundException {Properties p = new Properties();p.load(Test04.class.getClassLoader().getResourceAsStream("classPath.properties"));String path = p.getProperty("path");Class<?> clazz = Class.forName(path);//获取属性上的泛型类型Field field = ReflexUtil.getField(clazz, "map");Type fieldType = field.getGenericType();ParameterizedType fieldTypepPT = (ParameterizedType) fieldType;Type[] actualTypeArguments = fieldTypepPT.getActualTypeArguments();//获取泛型类型for (Type type : actualTypeArguments) {System.out.println(type);}System.out.println("---------------------------------------");Method method = ReflexUtil.getMethod(clazz, "method05", ArrayList.class,HashMap.class);//获取方法上参数的泛型类型Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {Type parameterizedType = parameter.getParameterizedType();ParameterizedType parameterTypepPT = (ParameterizedType) parameterizedType;Type[] actualTypeArguments2 = parameterTypepPT.getActualTypeArguments();for (Type type : actualTypeArguments2) {System.out.println(type);}}System.out.println("---------------------------------------");//获取方法上返回值的泛型类型Type genericReturnType = method.getGenericReturnType();ParameterizedType returnPT = (ParameterizedType) genericReturnType;Type[] actualTypeArguments2 = returnPT.getActualTypeArguments();for (Type type : actualTypeArguments2) {System.out.println(type);}}
}

9.利用反射操作注解

public class Test05 {public static void main(String[] args) throws IOException, ClassNotFoundException {Properties p = new Properties();p.load(Test05.class.getClassLoader().getResourceAsStream("classPath.properties"));String path = p.getProperty("path");Class<?> clazz = Class.forName(path);//获取类上的注解信息MyAnnotaction classAnnotation = clazz.getAnnotation(MyAnnotaction.class);System.out.println(classAnnotation.str());System.out.println("------------------------------------------------");//获取属性上的注解信息Field field = ReflexUtil.getField(clazz, "map");MyAnnotaction fieldAnnotation = field.getAnnotation(MyAnnotaction.class);System.out.println(fieldAnnotation.str());System.out.println("------------------------------------------------");//获取方法上的注解信息Method method = ReflexUtil.getMethod(clazz, "method05", ArrayList.class,HashMap.class);MyAnnotaction methodAnnotation = method.getAnnotation(MyAnnotaction.class);System.out.println(methodAnnotation.str());System.out.println("------------------------------------------------");//获取参数上的注解信息Parameter[] parameters = method.getParameters();for (Parameter parameter : parameters) {MyAnnotaction parameterAnnotation = parameter.getAnnotation(MyAnnotaction.class);if(parameterAnnotation != null){//说明该参数上有MyAnnotaction的注解System.out.println(parameterAnnotation.str());}}	}
}

MyAnnotaction类

@Target({TYPE,FIELD,METHOD,PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotaction {String str();}

10.利用反射操作数组

注意:Array – 该类是Java给我们提供专门利用反射去操作数组的类

public class Test06 {public static void main(String[] args) {//创建数组int[] arr = (int[]) Array.newInstance(int.class, 10);//获取数组长度int length = Array.getLength(arr);System.out.println("获取数组长度:" + length);//循环设置每个下标上的元素for (int i = 0; i < Array.getLength(arr); i++) {//设置当前下标上的元素Array.set(arr, i, i+1);}//循环获取每个下标上的元素for (int i = 0; i < Array.getLength(arr); i++) {//获取当前下标上的元素Object element = Array.get(arr, i);System.out.println(element);}}
}

10.反射工具类

package com.qf.utils;public class ReflexUtil {/*** 获取当前类及其父类的属性对象* @param clazz class对象* @param name 属性名* @return 属性对象*/public static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 设置对象中的属性* @param obj 对象* @param name 属性名* @param value 属性值*/public static void setField(Object obj,String name,Object value){Field field = getField(obj.getClass(), name);if(field != null){field.setAccessible(true);try {field.set(obj, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}/*** 创建对象* @param clazz class对象* @param paremeterType 构造方法中的参数类型数组* @param paremeters 构造方法中的参数数据* @return 对象*/public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] paremeters){try {Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);constructor.setAccessible(true);T obj = constructor.newInstance(paremeters);return obj;} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}return null;}/*** 获取方法对象* @param clazz class对象* @param name 方法名* @param parameterTypes 参数列表数组* @return 方法对象*/public static Method getMethod(Class<?> clazz,String name,Class<?>... parameterTypes){for(Class<?> c = clazz; c != null; c = c.getSuperclass()) {try {Method method = c.getDeclaredMethod(name, parameterTypes);return method;} catch (NoSuchMethodException e) {} catch (SecurityException e) {}}return null;}/*** 调用成员方法* @param obj 对象* @param name 方法名* @param parameterTypes 参数列表数组* @param paremeters 参数数据数组* @return 方法返回值*/public static Object invoke(Object obj,String name,Class<?>[] parameterTypes,Object[] paremeters){Class<? extends Object> clazz = obj.getClass();Method method = getMethod(clazz, name, parameterTypes);method.setAccessible(true);try {Object invoke = method.invoke(obj, paremeters);return invoke;} catch (IllegalAccessException e) {} catch (IllegalArgumentException e) {} catch (InvocationTargetException e) {}return null;}/*** 调用静态方法* @param clazz class对象* @param name 方法名* @param parameterTypes 参数列表数组* @param paremeters 参数数据数组* @return 方法返回值*/public static Object invoke(Class<?> clazz,String name,Class<?>[] parameterTypes,Object[] paremeters){Method method = getMethod(clazz, name, parameterTypes);method.setAccessible(true);try {Object invoke = method.invoke(null, paremeters);return invoke;} catch (IllegalAccessException e) {} catch (IllegalArgumentException e) {} catch (InvocationTargetException e) {}return null;}
}

简答题

1.获取Class实例的方式
类名.class
对象.getClass
类的全限定类名

2.如何通过反射创建类对象
Class aClass = Class.forName();
Constructor c = aClass.getConstructor(String.class);
Object o = c.newInstance(“hello”);

3.如何通过反射调用方法、设置字段
Method method = aClass.getMethod(“print”,String.class);
Object h = method.invoke(o,“你好”);
Field field = aClass.getField(“username”);
field.set(o,“Tom”);
Object f = field.get(o);

4.反射机制的优缺点:
优点:
1)能够运行时动态获取类的实例,提高灵活性;
2)与动态编译结合
缺点:
1)使用反射性能较低,需要解析字节码,将内存中的对象进行解析。
2)相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性)

5.哪里会用到反射机制?
jdbc就是典型的反射

Class.forName('com.mysql.jdbc.Driver.class');//加载MySQL的驱动类

这就是反射。如hibernate,struts等框架使用反射实现的。

总结

反射

获取class对象

操作属性

操作构造方法

操作方法

操作方法里的参数

操作方法里的返回值

操作泛型

操作注解

操作数组

重点:封装反射的工具类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/1233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fastadmin解决异步高并发大并发阻塞超时问题

官方连接​​​​​​https://guzzle-cn.readthedocs.io/zh_CN/latest/quickstart.html?highlightgetasync 使用guzzle 实现&#xff0c;需要先引用。安装请自行解决。 use GuzzleHttp\Client; use GuzzleHttp\Promise; /*** 异步高并发请求*/public function asyncRequests…

Android自定义类-写字板

目录 1. 属性文件 res/values/attrs.xml 2. 自定义控件类文件 MyClipbroad.class 3. XML布局文件中的使用 4. Java文件中的使用 该写字板可设置画笔颜色、画笔宽度、画布背景&#xff0c;具有导出图像、清空画布功能&#xff0c;可与OnTouchListener配合达到触摸绘画的效果…

速盾:cdn都能防御哪些攻击?

CDN&#xff08;Content Delivery Network&#xff09;是一种分布式的服务器网络&#xff0c;通过将资源缓存到多个服务器节点上&#xff0c;在用户请求资源时将其分发至最近的服务器节点&#xff0c;提供快速响应和高可用性。除了提供高速内容传输和优化用户体验之外&#xff…

算法课程笔记——STL键值对map

map当下标无限的数组 重点是对应关系&#xff0c;一般不修改compare 类比set 没有lowerbound&#xff0c;因为遍历是无序的 ; map不能用sort函数排序 但可用vector转化为map使用 std::set<std::pair<TKEY, mutable TVAL> > ≈ std::map<TKEY, TVAL>

使用 Cucumber框架进行BDD测试的一些项目

BehatMage 项目地址: https://github.com/MageTest/BehatMage 不过该项目在GitHub中有超过10年没有更新了。 项目介绍&#xff1a; BehatMage项目介绍 BehatMage是一个基于Behat的Magento测试框架&#xff0c;用于自动化测试Magento电子商务平台的功能和性能。Behat是一个行…

什么是认知负荷?

认知负荷&#xff08;Cognitive Load&#xff09;是心理学中的一个概念&#xff0c;它描述了一个人在特定时间内处理信息和进行思考所需耗费的认知资源的量。这个概念是由教育心理学家John Sweller在1988年提出的&#xff0c;主要用于描述学习过程中的认知需求。 认知负荷通常…

【剪映专业版】13快速为视频配好音:清晰、无噪声、对齐

视频课程&#xff1a;B站有知公开课【剪映电脑版教程】 使用场景&#xff1a;视频无声音或者视频有声音但是需要更改声音 时间指示器在哪里&#xff0c;就从哪里开始 红色按钮&#xff1a;开始录音 声音波纹&#xff1a;蓝色最佳&#xff0c;黄色或红色声音太大&#xff0c;…

23种设计模式之创建型模式篇

一、创建型模式 这类模式主要关注对象的创建过程。它们试图在创建对象的同时&#xff0c;将对象的创建和使用分离&#xff0c;以达到更高的灵活性和可扩展性. 包括: 工厂方法模式&#xff08;Factory Method&#xff09;抽象工厂模式&#xff08;Abstract Factory&#xff0…

C# 反射基础

1 在.NET中程序集是什么&#xff1f; 程序集&#xff08;Assembly&#xff09;以可执行文件(.exe)或动态链接库文件(.dll)的形式存在&#xff0c;是.NET应用程序构建的基本单元。程序集可用于部署、版本控制和设置安全权限等。 2.程序集的有哪些部分组成&#xff1f; 程序集…

Unity UGUI透明区域点击无效

是这样的&#xff0c;我有一张图&#xff0c;客户给的是1920*1080&#xff0c;但只有中间部分是按钮&#xff0c;是有效像素。为了让空白区域点击无效。需要设置如下 并且加上下面这句 this.GetComponent<Image>().alphaHitTestMinimumThreshold 0.1f;

tomcat中Pipeline-Valve解析

tomcat中用到Pipeline-Value有二种方式&#xff0c;一种是管道/阀门&#xff0c;另一种是过滤器链/过滤器。 管道/阀门过滤器链/过滤器管道&#xff08;Pipeline&#xff09;过滤器链&#xff08;FilterChain&#xff09;阀门&#xff08;Valve&#xff09;过滤器&#xff08;…

python学习笔记B-08:序列结构之列表--列表的遍历操作

列表的遍历方法主要有三种&#xff0c;使用方法和特点如下&#xff1a; lst list("hello") print("第一种遍历方式&#xff0c;使用for循环&#xff0c;循环变量item直接就是lst中的元素") for item in lst:print(item,end"\t")print("\n…

LeetCode 383.赎金信(模拟,for(char c : 容器)的使用)

给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&#…

第64天:服务攻防-框架安全CVE复现Apache ShiroApache Solr

目录 思维导图 案例一&#xff1a;Apache Shiro-组件框架安全 shiro反序列化 cve_2016_4437 CVE-2020-17523 CVE-2020-1957 案例二&#xff1a;Apache Solr-组件框架安全 远程命令执行 RCE&#xff08;CVE-2017-12629&#xff09; 任意文件读取 AND 命令执行&#xff08…

【java】(软考)面向对象---责任链解析

目录 责任链的意义 手写笔记 ​编辑 责任链的意义 当您把请求给出时&#xff0c;如果某对象不能实现您的操作&#xff0c;责任链会自动把您的请求传给它的下一级 从而避免请求的发送者和接受者之间的耦合关系 这里以2007年下半年试题七进行说明 题目描述 某企业的采购审批…

SpringBoot学习之Kafka下载安装和启动(三十三)

一、Mac环境 1、下载Kafka&#xff1a;Apache Kafka 2、这里我选择的版本是kafka_2.12-3.7.0&#xff0c;下载最新版的Kafka二进制文件&#xff0c;解压到你喜欢的目录&#xff08;建议目录不要带中文&#xff09;。 3、启动ZooKeeper服务&#xff0c;Kafka需要使用ZooKeeper&…

OpenHarmony 网络管理-Socket连接

介绍 本示例主要演示了Socket在网络通信方面的应用&#xff0c;展示了Socket在两端设备的连接验证、聊天通信方面的应用。 效果预览 使用说明 1.搭建服务器环境&#xff1a;修改服务器脚本中的服务端IP地址&#xff0c;与本机IP地址保持一致&#xff0c;修改完成后双击运行脚…

Zynq 7000 系列中的JTAG和DAP子系统

Zynq 7000系列SoC器件通过标准JTAG调试接口提供调试访问。在内部&#xff0c;SoC设备器件在处理系统&#xff08;PS&#xff09;内部实现了一个Arm调试访问端口&#xff08;DAP&#xff09;&#xff0c;同时在可编程逻辑&#xff08;PL&#xff09;内部实现了一个标准的JTAG测试…

minio如何配置防盗链

MinIO 是一个开源的对象存储服务器&#xff0c;用于存储大量的数据&#xff0c;同时提供了丰富的功能和 API。配置防盗链可以帮助你控制谁可以访问存储在 MinIO 上的对象。以下是在 MinIO 中配置防盗链的一般步骤&#xff1a; 编辑 config.json 文件&#xff1a; 找到 MinIO 服…

每日昨日之螺旋矩阵

螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 示例 2&#xff1a; 输入&#xff1a;…