注解与反射机制
注解与反射机制
一、注解
1.什么是注解
java.annotation包
Annotation是从JDK1.5开始引入的新技术,注解即可以对程序员解释又可以对程序解释
2.注解与注释的区别
注释:对程序员解释代码信息
注解:对程序和程序员解释代码信息
3.注解的所用
不是程序本身,可以对程序作出解释(与注释(comment)类似)
可以被其他程序(编译器)读取
4.注解的格式
注解是以“@注释名”在代码中存在的,还可以添加一些参数
例如:@SuppressWarnings(value=“unchecked”)
5.注解的应用
可以附加在package、class、method、field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制实现对这些数据的访问
6.内置注解
@Overrlde:定义在java.lang.Override中,此注解只适用于修饰方法,表示一个方法声明打算重写超类中的另一个方法声明
@Deprecated:定义在java.lang.Deprecated中.此注解可以用于修饰方法,属性,类。表示不鼓励使用这样的元素.通常是因为它很危险或者存在更好的选择
@SuppressWarnings:镇压警告,定义在java.lang.SuppressWarnings中用来抑制编译时的警告信息,与前两个注释有所不同.你需要添加参数才能正确使用。这些参数都是已经定义好了的.我们选择性的使用就好了
@SuppressWarnings(“all”)抑制所有类型的警告信息
@SuppressWarnings(“unchecked”)抑制单类型的警告信息
@SuppressWarnings(value={“unchecked”,“deprecation”})抑制多类型的警告信息
7.元注解
元注解的作用:负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明
这些类型和它们所支持的类在java.lang.annotation包中可以找到
(@Target,@Retention,@Documented,@Inherited )
@Target:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
@Retention:表示需要要在什么级别保存该注择信息,用于描述注解的生命周期
(SOURCE < CLASS <RUNTIME)
@Document:说明该注解将被包含在javadoc中
@lnherited:说明子类可以继承父类中的该注解
@MyAnnotation02
public class Test01<@MyAnnotation02 T> {
@MyAnnotation02
public String name;
@MyAnnotation02
public Test01() {
}
@MyAnnotation01
@MyAnnotation02
@MyAnnotation03("aaa")
@MyAnnotation04
@MyAnnotation05(name = "aaa")
@MyAnnotation06(names = {
"aaa","bbb"})
@MyAnnotation07(names={
"aaa","bbb"},username="撕裂的忧伤")
public void method(String str){
@MyAnnotation02
int i = 100;
System.out.println(i);
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解只能在方法上使用,并且没有参数
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation01 {
}
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解可以在方法、类、构造方法、属性、局部变量、泛型上使用,并且没有参数
*/
@Target({
METHOD,TYPE,CONSTRUCTOR,FIELD,LOCAL_VARIABLE,TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation02 {
}
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解可以在方法上使用,并且有一个参数
*/
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation03 {
String value();
}
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解可以在方法上使用,并且有一个参数
*/
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation04 {
String value() default "abc";//设置默认值
}
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解可以在方法上使用,并且有一个参数
*/
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation05 {
String name();
}
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解可以在方法上使用,并且有一个参数
*/
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation06 {
String[] names();
}
import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 该注解可以在方法上使用,并且有一个参数
*/
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation07 {
String[] names();
String username();
String password() default "00000000";
}
8.自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
分析:
@interface用来声明一个注解,格式:public @interface注解名{定义内容}
其中的每一个方法实际上是声明了一个配置参数.
方法的名称就是参数的名称.
返回值类型就是参数的类型(返回值只能是基本类型、Class、String、enum)
可以通过default来声明参数的默认值
如果只有一个参数成员,一般参数名为value()
注解元素必須要有值,我们定义注解元素时,经常使用空字符串.0作为默认值
import java.util.ArrayList;
public class test01 {
//重写的注解
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
//过时的注解
@Deprecated
public void method01(){
}
//镇压警告的注解
@SuppressWarnings("all")
public void method02(){
ArrayList list = new ArrayList();
list.add(134);
list.add("abc");
}
}
二、反射机制
1.含义:
使用到一个类,该类的class文件会加载到方法区,并且在堆中创建该类的class对象,class对象作为class文件的访问入口,反射就是获取class对象,拿到class对象就可以访问class文件(换言之,可以对该类为所欲为-属性、构造方法、方法)
public class Student extends Person{
private String classId;
private String id;
public Student() {
}
// private Student(String classId, String id) {
// this.classId = classId;
// this.id = id;
// }
public Student(String name, char sex, int age, String classId, String id) {
super(name, sex, age);
this.classId = classId;
this.id = id;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "Student [classId=" + classId + ", id=" + id + ", getName()=" + getName() + ", getSex()=" + getSex()
+ ", getAge()=" + getAge() + "]";
}
// private String method01(String str){
// System.out.println("私有的方法 :" + str);
// return "用良心做教育";
// }
public static void method02(){
System.out.println("静态的方法");
}
}
public class Person {
private String name;
private char sex;
private int age;
public Person() {
}
public Person(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
//反射工具类
public class ReflexUtil {
//获取该类及其父类所有的属性对象
public static List<Field> getAllField(Class<?> clazz){
List<Field> list = new ArrayList<>();
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
Field[] fields = c.getDeclaredFields();
Collections.addAll(list, fields);
}
return list;
}
//获取该类及其父类指定的属性对象
public static Field getField(Class<?> clazz,String fieldName){
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
try {
Field field = c.getDeclaredField(fieldName);
return field;
} catch (NoSuchFieldException e) {
//如果该类中找不到属性就会出现该异常
}
}
return null;
}
//设置对象中的属性
public static void setField(Object obj,String fieldName,Object value){
Field field = getField(obj.getClass(), fieldName);
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//获取该类及其父类所有的构造对象
public static List<Constructor<?>> getAllConstructor(Class<?> clazz){
List<Constructor<?>> list = new ArrayList<>();
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
Constructor<?>[] constructors = c.getDeclaredConstructors();
Collections.addAll(list, constructors);
}
return list;
}
//创建该类的对象
public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] values){
try {
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T t = constructor.newInstance(values);
return t;
} 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;
}
//获取该类及其父类所有的方法对象
public static List<Method> getAllMethod(Class<?> clazz){
List<Method> list = new ArrayList<>();
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
Method[] methods = c.getDeclaredMethods();
Collections.addAll(list, methods);
}
return list;
}
//获取指定的方法对象
public static Method getMethod(Class<?> clazz,String methodName,Class<?>... parameterTypes){
for(Class<?> c = clazz;c != null;c = c.getSuperclass() ){
try {
Method method = c.getDeclaredMethod(methodName, parameterTypes);
return method;
} catch (NoSuchMethodException e) {
}
}
return null;
}
//调用成员方法
public static Object invoke(Object obj,String methodName,Class<?>[] parameterTypes,Object[] values){
Method method = getMethod(obj.getClass(), methodName, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(obj, values);
return invoke;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
//调用静态方法
public static Object invoke(Class<?> clazz,String methodName,Class<?>[] parameterTypes,Object[] values){
Method method = getMethod(clazz, methodName, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(null, values);//静态方法直接填null,因为不需要对象去调用
return invoke;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
2.利用反射获取class对象
方案一
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
//方式1:通过该类的对象获取class对象
Student stu = new Student();
Class<? extends Student> class1 = stu.getClass();
//方式2:通过类名获取class对象
Class<? extends Student> class2 = Student.class;
//方式3:通过Class类的静态方法forName加上类的全路径获取class对象
Class<?> class3 = Class.forName("com.gl.reflex01.Student");
System.out.println(class1 == class2);//true
System.out.println(class2 == class3);//true
}
}
方案二
import java.io.IOException;
import java.util.Properties;
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<?> class1 = Class.forName(path);
System.out.println(class1.getName());
}
}
3.利用反射操作属性 – Field
public class Test03 {
public static void main(String[] args) throws Exception {
// 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);
// }
//获取该类及其父类所有的属性对象
// List<Field> fields = ReflexUtil.getAllField(clazz);
// for (Field field : fields) {
// System.out.println(field);
// }
//获取该类指定的公有的属性对象
// Field field = clazz.getField("classId");
// System.out.println(field);
//获取该类指定的属性对象
// Field field = clazz.getDeclaredField("classId");
// System.out.println(field);
//获取该类及其父类指定的属性对象
// Field field = ReflexUtil.getField(clazz, "name");
// System.out.println(field);
//利用反射机制去操作对象中的属性
// Student stu = new Student();
// Field fieldName = ReflexUtil.getField(clazz, "name");
// fieldName.setAccessible(true);//设置修改权限
// fieldName.set(stu, "关羽");
// System.out.println(stu);
//利用反射机制去操作对象中的属性 -- 封装成方法
Student stu = new Student();
ReflexUtil.setField(stu, "name", "关羽");
ReflexUtil.setField(stu, "sex", '男');
ReflexUtil.setField(stu, "age", 25);
ReflexUtil.setField(stu, "classId", "2022");
ReflexUtil.setField(stu, "id", "002");
System.out.println(stu);
}
}
4.利用反射操作构造方法
import java.util.Properties;
public class Test04 {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties"));
String path = p.getProperty("path");
@SuppressWarnings("unchecked")
Class<Student> clazz = (Class<Student>) 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);
// }
//获取该类及其父类所有的构造方法对象
// List<Constructor<?>> allConstructor = ReflexUtil.getAllConstructor(clazz);
// for (Constructor<?> constructor : allConstructor) {
// System.out.println(constructor);
// }
//获取该类指定的公有的构造方法对象并创建该类对象 -- 无参构造
// Constructor<?> constructor = clazz.getConstructor();//获取公有的无参构造
// Student stu = (Student) constructor.newInstance();//利用构造方法对象创建该类的对象
// System.out.println(stu);
//直接利用无参构造创建对象
// Student stu = (Student) clazz.newInstance();//底层:获取该类的无参构造对象,并创建该类的对象
// System.out.println(stu);
//获取该类指定的公有的构造方法对象并创建该类对象 -- 有参构造
// Constructor<?> constructor = clazz.getConstructor(String.class,char.class,int.class,String.class,String.class);//获取公有的有参构造
// Student stu = (Student) constructor.newInstance("刘备",'男',23,"2022","001");//利用构造方法对象创建该类的对象
// System.out.println(stu);
//获取该类指定的构造方法对象并创建该类对象 -- 私有的有参构造
// Constructor<?> constructor = clazz.getDeclaredConstructor(String.class,String.class);//获取有参构造
// constructor.setAccessible(true);//设置修改权限
// Student stu = (Student) constructor.newInstance("2022","001");//利用构造方法对象创建该类的对象
// System.out.println(stu);
//利用反射机制去创建该类的对象 -- 封装成方法
Student stu1 = ReflexUtil.newInstance(clazz, null, null);
System.out.println(stu1);
Student stu2 = ReflexUtil.newInstance(clazz,new Class[]{
String.class,char.class,int.class,String.class,String.class},new Object[]{
"刘备",'男',23,"2022","001"});
System.out.println(stu2);
}
}
5.利用反射操作方法
import java.util.Properties;
public class Test05 {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.load(Test03.class.getClassLoader().getResourceAsStream("classpath.properties"));
String path = p.getProperty("path");
@SuppressWarnings("unchecked")
Class<Student> clazz = (Class<Student>) 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);
// }
//获取该类及其父类所有的方法对象
// List<Method> list = ReflexUtil.getAllMethod(clazz);
// for (Method method : list) {
// System.out.println(method);
// }
//调用公有的方法 -- 无参数的方法
// Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
// Method method = clazz.getMethod("getClassId");
// Object invoke = method.invoke(stu);
// System.out.println("返回值:" + invoke);
//调用公有的方法 -- 有参数的方法
// Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
// Method method = clazz.getMethod("setClassId",String.class);
// Object invoke = method.invoke(stu,"2212");
// System.out.println("返回值:" + invoke);
// System.out.println(stu);
//调用私有的方法
// Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
// Method method = clazz.getDeclaredMethod("method01", String.class);
// method.setAccessible(true);
// Object invoke = method.invoke(stu, "abc");
// System.out.println("返回值:" + invoke);
//调用方法 -- 封装方法
// Student stu = ReflexUtil.newInstance(clazz,new Class[]{String.class,char.class,int.class,String.class,String.class},new Object[]{"刘备",'男',23,"2022","001"});
// Object invoke = ReflexUtil.invoke(stu, "method01", new Class[]{String.class}, new Object[]{"abc"});
// System.out.println("返回值:" + invoke);
//调用静态方法
Object invoke = ReflexUtil.invoke(clazz, "method02", null,null);
System.out.println("返回值:" + invoke);
}
}
6.利用反射操作泛型
注意:类上的泛型是获取不到的
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
public class Test06 {
public static void main(String[] args) throws Exception {
Class<?> clazz = Test06.class;
Method method = clazz.getDeclaredMethod("method", ArrayList.class,HashMap.class);
//获取参数上的泛型
Type[] genericParameterTypes = method.getGenericParameterTypes();//获取参数类型
for (Type type : genericParameterTypes) {
ParameterizedType pt = (ParameterizedType) type;//把type强转为参数类型
Type[] actualTypeArguments = pt.getActualTypeArguments();//获取参数类型上的泛型并返回泛型数组(为什么返回的是数组?因为一个参数上有可能有多个泛型)
for (Type t : actualTypeArguments) {
System.out.println(t);
}
}
System.out.println("-------------");
//获取返回值上的泛型
Type genericReturnType = method.getGenericReturnType();
ParameterizedType pt = (ParameterizedType)genericReturnType;
Type[] actualTypeArguments = pt.getActualTypeArguments();//获取返回值类型上的泛型并返回泛型数组(为什么返回的是数组?因为一个参数上有可能有多个泛型)
for (Type type : actualTypeArguments) {
System.out.println(type);
}
}
public HashMap<String, Integer> method(ArrayList<String> list,HashMap<String, Integer> map){
return null;
}
}
7.利用反射操作数组
Arrays -- 数组的工具类
Array --- 数组的反射类
import java.lang.reflect.Array;
public class Test07 {
public static void main(String[] args) throws Exception {
//创建数组
int[] is = (int[]) Array.newInstance(int.class, 5);
//获取数组的长度
System.out.println("获取数组的长度:" + Array.getLength(is));//5
//通过下标设置元素
Array.set(is, 2, 888);
//遍历数组
for(int i = 0;i<Array.getLength(is);i++){
//通过下标获取元素
Object element = Array.get(is, i);
System.out.println(element);
}
}
}
8.反射机制 之 扩展运用封装代码
public class Person {
private String name;
private char sex;
private int age;
public Person() {
}
public Person(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [names=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
//反射工具类
public class ReflexUtil {
//获取该类及其父类所有的属性对象
public static List<Field> getAllField(Class<?> clazz){
List<Field> list = new ArrayList<>();
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
Field[] fields = c.getDeclaredFields();
Collections.addAll(list, fields);
}
return list;
}
//获取该类及其父类指定的属性对象
public static Field getField(Class<?> clazz,String fieldName){
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
try {
Field field = c.getDeclaredField(fieldName);
return field;
} catch (NoSuchFieldException e) {
//如果该类中找不到属性就会出现该异常
}
}
return null;
}
//设置对象中的属性
public static void setField(Object obj,String fieldName,Object value){
Field field = getField(obj.getClass(), fieldName);
field.setAccessible(true);
try {
field.set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
//获取该类及其父类所有的构造对象
public static List<Constructor<?>> getAllConstructor(Class<?> clazz){
List<Constructor<?>> list = new ArrayList<>();
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
Constructor<?>[] constructors = c.getDeclaredConstructors();
Collections.addAll(list, constructors);
}
return list;
}
//创建该类的对象
public static <T> T newInstance(Class<T> clazz,Class<?>[] parameterTypes,Object[] values){
try {
Constructor<T> constructor = clazz.getDeclaredConstructor(parameterTypes);
constructor.setAccessible(true);
T t = constructor.newInstance(values);
return t;
} 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;
}
//获取该类及其父类所有的方法对象
public static List<Method> getAllMethod(Class<?> clazz){
List<Method> list = new ArrayList<>();
for (Class<?> c = clazz;c != null;c = c.getSuperclass()) {
Method[] methods = c.getDeclaredMethods();
Collections.addAll(list, methods);
}
return list;
}
//获取指定的方法对象
public static Method getMethod(Class<?> clazz,String methodName,Class<?>... parameterTypes){
for(Class<?> c = clazz;c != null;c = c.getSuperclass() ){
try {
Method method = c.getDeclaredMethod(methodName, parameterTypes);
return method;
} catch (NoSuchMethodException e) {
}
}
return null;
}
//调用成员方法
public static Object invoke(Object obj,String methodName,Class<?>[] parameterTypes,Object[] values){
Method method = getMethod(obj.getClass(), methodName, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(obj, values);
return invoke;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
//调用静态方法
public static Object invoke(Class<?> clazz,String methodName,Class<?>[] parameterTypes,Object[] values){
Method method = getMethod(clazz, methodName, parameterTypes);
method.setAccessible(true);
try {
Object invoke = method.invoke(null, values);//静态方法直接填null,因为不需要对象去调用
return invoke;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
return values;
}
}
public class Student extends Person{
private String classId;
private String id;
public Student() {
}
public Student(String name, char sex, int age, String classId, String id) {
super(name, sex, age);
this.classId = classId;
this.id = id;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
// private String method01(String str){
// System.out.println("私有的方法 :" + str);
// return "用良心做教育";
//}
@Override
public String toString() {
return "Student [classId=" + classId + ", id=" + id + ", getName()=" + getName() + ", getSex()=" + getSex()
+ ", getAge()=" + getAge() + "]";
}
public static void method02(){
System.out.println("静态的方法");
}
}
9.反射机制 之 扩展属性的运用
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Properties;
public class Test01 {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.load(Test01.class.getClassLoader().getResourceAsStream("classpath.properties"));
String path = p.getProperty("path");
Class<?> clazz = Class.forName(path);
//获取学生类中的name属性
Field field = ReflexUtil.getField(clazz, "name");
//获取属性参数值
int modifiers = field.getModifiers();
System.out.println("判断属性是否是私有化的:" + Modifier.isPrivate(modifiers));
System.out.println("判断属性是否是Protected的:" + Modifier.isProtected(modifiers));
System.out.println("判断属性是否是公有的:" + Modifier.isPublic(modifiers));
System.out.println("判断属性是否是静态的:" + Modifier.isStatic(modifiers));
System.out.println("判断属性是否是常量的:" + Modifier.isFinal(modifiers));
}
}
10.反射机制 之 扩展方法的运用
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Properties;
public class Test02 {
@SuppressWarnings("all")
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.load(Test02.class.getClassLoader().getResourceAsStream("classpath.properties"));
String path = p.getProperty("path");
Class<?> clazz = Class.forName(path);
//获取学生类中的method02
Method method = ReflexUtil.getMethod(clazz, "method02",null);
//获取方法参数值
int modifiers = method.getModifiers();
System.out.println("判断方法是否是私有化的:" + Modifier.isPrivate(modifiers));
System.out.println("判断方法是否是Protected的:" + Modifier.isProtected(modifiers));
System.out.println("判断方法是否是公有的:" + Modifier.isPublic(modifiers));
System.out.println("判断方法是否是静态的:" + Modifier.isStatic(modifiers));
System.out.println("判断方法是否不可重写的:" + Modifier.isFinal(modifiers));
System.out.println("判断方法是否同步的:" + Modifier.isSynchronized(modifiers));
System.out.println("判断方法是否抽象的:" + Modifier.isAbstract(modifiers));
}
}
11.反射案例之万能数组扩容/复制
import java.lang.reflect.Array;
import java.util.Arrays;
public class Test01 {
public static void main(String[] args) {
int[] is = {
1,2,3,4,5};
int[] copy1 = copy(is,10);
System.out.println(Arrays.toString(copy1));
System.out.println("---------");
String[] names = {
"后裔","狄仁杰","李元芳","孙尚香"};
String[] copy2 = copy(names,10);
System.out.println(Arrays.toString(copy2));
}
public static <T> T copy(T t,int newLength){
//获取数组的class对象
Class<? extends Object> clazz = t.getClass();
//获取数组元素类型的class对象
Class<?> elementClazz = clazz.getComponentType();
//创建数组
@SuppressWarnings("unchecked")
T arr = (T) Array.newInstance(elementClazz, newLength);
//遍历原数组
for (int i = 0; i < Array.getLength(t); i++) {
//获取指定下标上的元素
Object element = Array.get(t, i);
//将元素设置给新数组
Array.set(arr, i, element);
}
return arr;
}
}
12.反射案例 之 逻辑与业务分离的思想
- 业务场景:获取数据
- 分析:
- 获取本地数据 – 代码
- 获取网络数据 – 代码
获取其他数据 – 代码
import java.util.List;
import java.util.Scanner;public class Test01 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
printMenu();
int num = scan.nextInt();
DataSource dataSource = getDataSourceObj(num);
dataSource.getDataSource();
scan.close();
}
public static DataSource getDataSourceObj(int num){
List<String> classlist = DataContainer.classList;
String classPath = classlist.get(num-1);
try {
Class<?> clazz = Class.forName(classPath);
DataSource dataSource = (DataSource) clazz.newInstance();
return dataSource;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
private static void printMenu() {
List<String> menulist = DataContainer.menuList;
System.out.println("请选择获取数据的方式:");
for (String str : menulist) {
System.out.println(str);
}
}
}
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DataContainer {
public static final List<String> menuList;
public static final List<String> classList;
static{
//初始化菜单集合
menuList = new ArrayList<>();
Properties menuProperties = new Properties();
try {
menuProperties.load(DataContainer.class.getClassLoader().getResourceAsStream("menuConfig.properties"));
} catch (IOException e) {
e.printStackTrace();
}
String menu = menuProperties.getProperty("menu");
String[] menuSplit = menu.split(",");
for (String str : menuSplit) {
menuList.add(str);
}
//初始化类路径集合
classList = new ArrayList<>();
Properties classProperties = new Properties();
try {
classProperties.load(DataContainer.class.getClassLoader().getResourceAsStream("classConfig.properties"));
} catch (IOException e) {
e.printStackTrace();
}
String path = classProperties.getProperty("path");
String[] pathSplit = path.split(",");
for (String str : pathSplit) {
classList.add(str);
}
}
}
public abstract class DataSource {
public abstract void getDataSource();
}
public class LocalDataSource extends DataSource{
@Override
public void getDataSource() {
System.out.println("执行获取本地数据的代码...");
}
}
public class NetworkDataSource extends DataSource{
@Override
public void getDataSource() {
System.out.println("执行获取网络数据的代码...");
}
}
public class OtherDataSource extends DataSource{
@Override
public void getDataSource() {
System.out.println("执行获取其他数据的代码...");
}
}
13.反射案例 之 获取注解信息
import java.lang.reflect.Field;
public class Test01 {
public static void main(String[] args) {
Student stu = new Student("刘备", '男', 23);
Class<? extends Student> clazz = stu.getClass();
//获取类上注解的信息
TableInfo tableInfoAnnotation = clazz.getAnnotation(TableInfo.class);
String tableName = tableInfoAnnotation.value();
System.out.println(tableName);
//获取属性上注解的信息
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
FieldInfo fieldInfoAnnotation = field.getAnnotation(FieldInfo.class);
String name = fieldInfoAnnotation.name();
String type = fieldInfoAnnotation.type();
int length = fieldInfoAnnotation.length();
Object value = null;
try {
field.setAccessible(true);
value = field.get(stu);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(name + " -- " + type + " -- " + length + " -- " + value);
}
//insert into s_student(s_name,s_sex,s_age) values("刘备","男",23)
}
}
@TableInfo("s_student")
public class Student {
@FieldInfo(name="s_name",type="varchar",length=32)
private String name;
@FieldInfo(name="s_sex",type="varchar",length=32)
private char sex;
@FieldInfo(name="s_age",type="int",length=3)
private int age;
public Student() {
}
public Student(String name, char sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableInfo {
String value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldInfo {
String name();
String type();
int length();
}
还没有评论,来说两句吧...