反射
反射:专门为框架而生,在框架里面用的反射非常多。SSH(Struts2/Hibernate持久层(把数据给持久化)/Spring) SSM(Spring SpringMVCMybatis)
Javaweb
框架:把咱们经常使用的一些东西,封装起来,来简化操作。
类字节码文件是在硬盘上存储的,是一个个的.class文件。我们在new一个对象时,JVM会先把字节码文件的信息读出来放到内存中,第二次用时,就不用在加载了,而是直接使用之前缓存的这个字节码信息。
字节码的信息包括:类名、声明的方法、声明的字段等信息。在Java中“万物皆对象”,这些信息当然也需要封装一个对象,这就是Class类、Method类(方法)、Field类(描述属性)Constructor(描述构造方法)。
通过Class类、Method类、Field类等等类可以得到这个类型的一些信息,甚至可以不用new关键字就创建一个实例,可以执行一个对象中的方法,设置或获取字段的值,这就是反射技术。
package com.reflect;
/**
* @author 谢英亮
* @date 2017年12月22日 下午2:58:47
* @Description: 学生类
*/
public class Student {
private String name;
private int age;
private String sex;
public void say(){
System.out.println("how are you?");
}
public void say(String to){
System.out.println("how are you?"+to);
}
private void say1(String to){
System.out.println("how are you?"+to);
}
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
private Student(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
}
package com.reflect;
/**
* 获取Class文件对象的三种方式
* 1.类名.class
* 2.对象.getClass()
* 3.Class.forName("类的全限定名") 类的全限定名:包名+类名 (这种用的最多 推荐)
*
* 框架:配置文件 .properties配置文件 .xml配置文件
* 1. getName()类的名称(全名,全限定名)
2 getSimpleName()类的的简单名称(不带包名)
3. getModifiers(); 类的的修饰符
4.创建对象
无参数构造创建对象
newInstance()
*
*/
/**
* @author 谢英亮
* @date 2017年12月22日 下午2:58:08
* @Description:
*/
public class TestClass {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
/**
* 1.类名.class
*/
Class<Student> clz=Student.class;
System.out.println(clz);//class com.reflect.Student
/**
* 2.对象.getClass()
* ? extends Student Student和Student的子类
*/
Class<? extends Student> clz1 = new Student().getClass();
System.out.println(clz1);
System.out.println(clz==clz1);
/**
* Class.forName("类的全限定名") 类的全限定名:包名+类名 (这种用的最多 推荐)
*/
Class<?> clz2 = Class.forName("com.reflect.Student");
System.out.println("getName()类的名称"+clz.getName());
System.out.println("getSimpleName()类的的简单名称"+clz.getSimpleName());
System.out.println(clz.getModifiers());
Student s = clz.newInstance();
System.out.println(s);
}
}
package com.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
/**
* @author 谢英亮
* @date 2017年12月22日 下午2:59:25
* @Description:
*/
public class TestClassConstractor {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> clz = Class.forName("com.reflect.Student");
/**
* 获取构造函数
* getConstructor:只能获取被public修饰的构造函数
*/
Constructor<?> constructor = clz.getConstructor();
/*Constructor<?> constructor1 = clz.getConstructor(String.class,int.class,String.class);*/
System.out.println(constructor);
// System.out.println(constructor1);
/**
* 实例化对象
* newInstance
*/
Student s1 = (Student) constructor.newInstance();
System.out.println(s1);
// Student s2 = (Student) constructor1.newInstance("小明",12,"男");
// System.out.println(s2);
/**
* getDeclaredConstructor()可以获取不被public修饰的构造
* newInstance()
* setAccessible(true);
*/
Constructor<?> declaredConstructor = clz.getDeclaredConstructor(String.class,int.class,String.class);
System.out.println(declaredConstructor);
declaredConstructor.setAccessible(true);
Student s3 = (Student) declaredConstructor.newInstance("小明",12,"男");
System.out.println(s3);
Constructor<?>[] declaredConstructors = clz.getDeclaredConstructors();
System.out.println(Arrays.toString(declaredConstructors));
}
}
package com.reflect;
import java.lang.reflect.Field;
public class TestClassField {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
Class<Student> clz = (Class<Student>) Class.forName("com.reflect.Student");
/**
* getField()只能获得被public修饰 还可以从父类继承过来的
* getDeclaredField()都可以获得
*
*/
//Field field = clz.getField("xxx");
//Field field1 = clz.getField("name");
Field name= clz.getDeclaredField("name");
//System.out.println(field);
System.out.println(name);
/**
* Map<field,值>
*/
Field[] declaredFields = clz.getDeclaredFields();
Student s = clz.newInstance();
//name setName()
char c = name.getName().charAt(0);
String upperCase = (c+"").toUpperCase();
String re="set"+upperCase+name.getName().substring(1);
System.out.println(re);
//clz.getMethod("", "小明");
/*for(Field item:declaredFields){
System.out.println(item.getName());
}*/
}
}
package com.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @author 谢英亮
* @date 2017年12月22日 下午3:01:31
* @Description: 通过反射获取方法
*/
public class TestClassMethod {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class<?> clz = Class.forName("com.reflect.Student");
/**
* 获得有参和无参数的方法
* getMethod()
* 1.只能获得被public 修饰的方法,
* 2.还可以获得从父类中继承过来的
*/
Method method = clz.getMethod("say");
Method method1 = clz.getMethod("say",String.class);//String.class int.class double.class
System.out.println(method);
System.out.println(method1);
/**
* 调用方法:invoke(obj,实参)
*/
method.invoke(clz.newInstance());
method1.invoke(clz.newInstance(),"康康");
Method m = clz.getMethod("wait");
System.out.println(m);
Method[] methods = clz.getMethods();
System.out.println(Arrays.toString(methods));
/**
*getDeclaredMethod()
*1. 可以获得私有的被 private修饰
*2.都不能获得从父类继承过来的方法
*/
Method say1 = clz.getDeclaredMethod("say1", String.class);
//Method w = clz.getDeclaredMethod("wait");
//System.out.println(w);
System.out.println(say1);
/**
* 强制可见
*/
say1.setAccessible(true);
say1.invoke(clz.newInstance(), "jane");
Method[] declaredMethods = clz.getDeclaredMethods();
System.out.println(Arrays.toString(declaredMethods));
}
}