1反射
定义:使用一种技术在程序运行时就能去操作java对象中的属性、方法、构造方法等。
使用过程
1.2 类 获取字节码对象,Class类对应的对象
(1) 类名.class
(2)Class.forName("完全限定名");
右键绿色Test选Copy Qualified Name
(3) 对应的一个类对象.get.Class();
1.3 接口 获取字节码对象,Class类对应的对象
(1) 类名.class
(2)Class.forName(完全限定名)
(3)接口不能实例化
1.4 数组 获取字节码对象,Class类对应的对象
(1)数组类型.class
(2)数组对象.getClass()
1.5数据类型/void(无类型) 获取字节码对象,Class类对应的对象
(1) 类名.class
(2)包装类.TYPE
int.class Integer.class Integer.TYPE void.class Void.TYPE1.3
2反射创建对象
2.1类中构造是公共无参的,直接通过调用类中的newInstance方法
Class<Person> clz= Person.class;
Person stu = clz.newInstance();
System.out.println(stu);
2.2类中构造是公共有参的,通过获取构造函数对象来操作
Class<Person> clazz2=Person.class;
//2.调用getConstructor(参数类型的Class对象)来获取到构造对象
Constructor<Person> con= clazz2.getConstructor(参数类型.class,参数类型.class);
//3.构造对象调用newInstance(实际的参数值)来创建对象
Person p4= con.newInstance("李四","20");
//4.输出打印
System.out.println(p4.toString());
2.3类中构造是私有无参的:
Constructor<Person2> p3 = clazz.getDeclaredConstructor();
p3.setAccessible(true);//设定访问权限设置访问级别,若是私有构造函数,则设置为true用于访问该构造方法,不会去掉private修饰符,访问一次,设置一次
Person2 pp = p3.newInstance();
System.out.println(pp.toString());
2.4类中构造是私有有参的:
//1.获取Class实例对象
Class<Person> clazz3=Person.class;
//2.实例对象通过getDeclaredConstructor(参数类型的Class实例对象)获取构造对象(Constructor)
Constructor<Person> con2=
clazz3.getDeclaredConstructor(String.class,String.class);
//3.设置默认访问级别为true setAccessible(true)
con2.setAccessible(true);
//4.通过构造对象调用newInstance(实际的参数值)来创建对象
Person p5= con2.newInstance("王五","21");
//5.输出打印
3 反射调用方法
Class类:
getMethod(方法名,参数字节码对象【可变参数】)
根据指定方法名和参数返回一个Method对象
getDeclaredMethod(方法名,参数字节码对象【可变参数】)
根据指定方法名和参数返回一个Method对象
Method类:
setAccessible(boolean b)
若获取的Method对象是私有的,需要使用该方法设置方法的访问级别
invoke(方法归属的对象,方法实参【可变参数】)
调用实际类对象中的方法,并返回该方法的结果
调用的方法是公共有参的
//1.获得class的实例对象
Class<Person> clazz= Person.class;
//2.获得类对象
Person p= clazz.newInstance();
//3.获得方法对象
Method method= clazz.getMethod("setName", String.class);
//4.使用Invoke来调用
method.invoke(p, "张三");
//5.输出Person中的name
System.out.println(p.getName());
调用的方法是公共无参的
//1.获得class的实例对象
Class<Person> clazz= Person.class;
//2.获得类对象
Person p= clazz.newInstance();
//3.获得方法对象
Method method= clazz.getMethod("方法名run");
//4.使用Invoke来调用
method.invoke(类对象p);
方法是私有无参
//1.获得class的实例对象
Class<Person> clazz= Person.class;
//2.获得类对象
Person p= clazz.newInstance();
//3.获得方法对象
Method method= clazz.getDeclaredMethod("run");
//4.设计权限
Method.setAccessible(true);
//5.使用Invoke来调用
method.invoke(p);
方法是私有有参
//1.获得class的实例对象
Class<Person> clazz= Person.class;
//2.获得类对象
Person p= clazz.newInstance();
//3.获得方法对象
Method method= clazz.getDeclaredMethod("run",String.class);
Method.setAccessible(true);//设定访问权限设置访问级别,若是私有构造函数,则设置为true用于访问该构造方法,不会去掉private修饰符,访问一次,设置一次
//4.使用Invoke来调用
method.invoke(p,”你跑啊”);
4 反射操作类里的字段
getField(字段名)
获取字节码对象中指定的公共的字段对象
getDeclaredField(字段名)
获取字节码对象中指定的字段对象
Field类:
setAccessible(Boolean b)
设置字段的访问级别
get(字段归属的类对象)
获取字段的值
set(字段归属的类对象,实际值)
设置字段的值
Class<Students> clz= Students.class;
Students stu = clz.newInstance();
Field field = clz.getDeclaredField("name");
field.setAccessible(true);
field.set(stu, "心智");
System.out.println(field.get(stu));
System.out.println(stu.getName());
5 通过反射 相关函数函数获取类的共有函数名,和私有函数名
* getMetods() 拿到所有的公共方法 如:函数名
到方法的返回值类型的类类型 getReturnType(); 返回类型,void1,或8种基本数据类型
获取参数类型 getParameterTypes() 参数类型封装成数组 如:形式参数
package homework.day12;
import java.lang.reflect.Method;
public class GetFuctionName {
public static void main(String[] args) {
Person person = new Person();
printClassMethodMessage(person);
}
public static void printClassMethodMessage(Person Person) {// 该类所属 的信息
// 要获取类的信息,首先要获取类的类类型
Class class1 = Person.getClass(); // 传递的是哪个子类的对象,class1就是该子类的类类型
// 获取类的名称 class1.getName()
System.out.println("类的名称是:" + class1.getName());
/**
* Method类,方法对象 一个成员方法就是一个Method对象 getMehtod()方法
* 获取的是所有得public的函数,包括父类继承的 getDeclaredMethods()获取的是所有该类声明的方法,不同访问权限
* getMetods() 拿到所有的公共方法
*/
Method[] mes = class1.getMethods();
for (int i = 0; i < mes.length; i++) {
// 得到方法的返回值类型的类类型 getReturnType();
Class<Person> returnType = (Class<homework.day12.Person>) mes[i].getReturnType();
System.out.print(returnType.getName() + " ");
// 得到方法的名称
System.out.print(mes[i].getName() + "(");
// 获取参数类型 getParameterTypes() 参数类型封装成数组
Class[] paramTypes = mes[i].getParameterTypes();
for (Class class2 : paramTypes) {
System.out.print(class2.getName() + ",");
}
System.out.println(")");
}
//首先拿到私有化方法,再设置权限ms[i].setAccessible(true);
Method[] mes1 = class1.getDeclaredMethods();
for (int i = 0; i < mes1.length; i++) {
mes1[i].setAccessible(true);
// 得到方法的返回值类型的类类型 getReturnType();
Class<Person> returnType = (Class<homework.day12.Person>) mes1[i].getReturnType();
System.out.print(returnType.getName() + " ");
// 得到方法的名称
System.out.print(mes1[i].getName() + "(");
// 获取参数类型 getParameterTypes() 参数类型封装成数组
Class[] paramTypes = mes1[i].getParameterTypes();
for (Class class2 : paramTypes) {
System.out.print(class2.getName() + ",");
}
System.out.println(")");
}
}
}
6 构造函数有权权限的
无参 拿到字节码对象,通过对象方法实例化
有参 拿到字节码对象,得到构造对象,传入参数 类型字节码对象,通过对象方法实例化
1.2构造方法无权限的
无参 拿到字节码对象,得到构造对象,修改权限
通过对象方法实例化
有参 拿到字节码对象,得到构造对象,传入参数 类型字节码对象修改权限通 ,通过对象方法实例化
成员方法与成员变量类似
构造对象改为方法或变量对象
7 注解
定义:与类,接口,同级的一种结构
使用
@符号开头
使用位置前或后
注解作用:注解解释类,也就是相关对代码进行解释的特定类。一般这些类使用反射是可以拿到的。
元注解:注解的注解,用于自定义注解
8 单元测试
作用: 测试程序是否有BUG
用法:项目右键,build path ->configure build path->librars->add libary->junit->JUILT4
@Test按快捷键出来测试函数
Junit4 jdk1.5以后的用的,因为JDK1.5后支持注释。
类中单元测试方法可以调用静态方法,说明用了@Test的方法不属于类成员方法了
注意1 方法必须是公共无参的,没有返回值。
9.java中注释和注解于什么区别啊?
首先来说注释有三种:// /* */ /** */ 前两种编译器直接跳过,从来不阅读,第三种编译器是可以看懂的,当你使用javadoc这样的命令时会用到,用来生成API时用的。
注解:这东东完全就是给编译器看的。 比如@Ovrride表示这个方法是重写了父类中的方法,而不是自定义的,所以这个时候编译器会去检查你的方法名是否和父类一样,是否写错了。
起初,注解是比较简单的,后来注解里面可以加入变量和参数,以节省代码(这些代码都是大家共同认可的,用一个公式给代替了)
注解是对计算机的说明,也可以不用注解,自己写代码告诉计算机编译器。 注解其实就是代码,只是看起来和我们自己写的有点不一样而已。也是代码的一部分,学习Hibernate和Spring等的时候会大量用到注解,用来节省大量代码。
10.