反射
获取class对象的三种方法
①:Class.forName("全类名");
②:类名.class
③:对象.getclass();
代码样例
package com.ithema;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
//第一种方式
//最为常用
Class aClass1 = Class.forName("com.ithema.student");
System.out.println(aClass1);
//第二种方式
//一般更多作为参数传递传递
Class aClass2 = student.class;
System.out.println(aClass2);
//第三种方式
//当有了这个类的对象时才可以使用
student s=new student();
Class aClass3 = s.getClass();
System.out.println(aClass3);
}
}
利用反射获取构造方法
代码样例
package ithema;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取字节码文件对象
Class aClass1 = Class.forName("ithema.student");
//2.获取构造方法
//获取public修饰的构造方法
// Constructor[] cons = aClass1.getConstructors();
// for (Constructor con : cons) {
// System.out.println(con);
// }
//获取所有的构造方法
// Constructor[] cons2 = aClass1.getDeclaredConstructors();
// for (Constructor con : cons2) {
// System.out.println(con);
// }
//获取单个的构造方法
// Constructor con1 = aClass1.getDeclaredConstructor();
// System.out.println(con1);
//
// Constructor con2 = aClass1.getDeclaredConstructor(String.class);
// System.out.println(con2);
//
// Constructor con3 = aClass1.getDeclaredConstructor(int.class);
// System.out.println(con3);
Constructor con4 = aClass1.getDeclaredConstructor(String.class, int.class);
System.out.println(con4);
//获得权限修饰符
int modifiers = con4.getModifiers();
System.out.println(modifiers);
//得到构造方法所有的参数类型
Parameter[] parameters = con4.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
//通过反射得到的构造方法创建对象
//暴力反射:临时取消权限校验
con4.setAccessible(true);
student stu = (student) con4.newInstance("张三", 23);
System.out.println(stu);
}
}
里面的学生类对象代码:
package ithema;
public class student {
String name;
int age;
public student() {
}
public student(String name) {
this.name = name;
}
protected student(int age) {
this.age = age;
}
private student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
利用反射获取成员变量
代码样例
package adsads;
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
//第一种方式
//最为常用
Class aClass1 = Class.forName("adsads.student");
//获取所有成员变量
// Field[] fields = aClass1.getDeclaredFields();
// for (Field field : fields) {
// System.out.println(field);
// }
//获取单个成员变量
Field name = aClass1.getDeclaredField("name");
System.out.println(name);
//获取权限修饰符
int modifiers = name.getModifiers();
System.out.println(modifiers);
//获取成员变量的名字
String n=name.getName();
System.out.println(n);
//获取成员变量的数据类型
Class<?> type = name.getType();
System.out.println(type);
//获取成员变量记录的值
student s=new student("张三",32,"男");
name.setAccessible(true);
String value =(String) name.get(s);
System.out.println(value);
//修改对象里面记录的值
name.set(s,"list");
System.out.println(s);
}
}
里面的学生类对象代码:
package adsads;
public class student {
private String name;
private int age;
public String gender;
public student() {
}
public student(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
@Override
public String toString() {
return "student{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
利用反射获取成员方法
package ads;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//第一种方式
//最为常用
Class aClass1 = Class.forName("ads.student");
//获取里面所有的方法对象(包含父类公共的)
// Method[] methods = aClass1.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//获取里面所有的方法对象(不包含父类,但是可以获取本类中私有的)
// Method[] methods1 = aClass1.getDeclaredMethods();
// for (Method method : methods1) {
// System.out.println(method);
// }
//获取指定的单一方法
Method m = aClass1.getDeclaredMethod("eat", String.class);
System.out.println(m);
//获取方法的修饰符
int modifiers = m.getModifiers();
System.out.println(modifiers);
//获取方法的名字
String name = m.getName();
System.out.println(name);
//获取方法的形参
Parameter[] parameters = m.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
//获取方法抛出的异常
Class[] exceptionTypes = m.getExceptionTypes();
for (Class exceptionType : exceptionTypes) {
System.out.println(exceptionType);
}
//方法运行
student s=new student();
m.setAccessible(true);
//参数1:s 表示方法的调用者
//参数2:汉堡包 表示调用方法的时候传递的实际参数
m.invoke(s,"汉堡包");
}
}
里面的学生类对象代码:
package ads;
import java.io.IOException;
public class student {
private String name;
private int age;
public student() {
}
public student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void sleep(){
System.out.println("睡觉");
}
private void eat(String something)throws IOException ,NullPointerException{
System.out.println("在吃"+something);
}
}
反射的作用
获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑
结合配置文件,动态的创建对象并调用方法
注解
就是Java代码里的特殊标记,比如:@Override、@Test等,作用是:让其他程序根据注解信息来决定怎么执行该程序。
注意:注解可以用在类上、构造器上、方法上、成员变量上、参数上、等位置处。
自定义注解
注解的原理
元注解
修饰注解的注解
注解的解析
什么是注解的解析?
就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来
如何解析注解?
指导思想:要解析谁上面的注解,就应该先拿到谁。
比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解
比如要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析
其上面的注解。
Class、Method、Field,Constructor、都实现了AnnotatedElement接口,它们都拥有解析注解的能力。
类上面注解的解析
方法上面的解析
注解的作用:如可以用自定义注解来进行实现执行加了注解的方法,不执行不加注解的方法