咱们建立一个类,经过编译,生成对应的.calss文件,以后使用java.exe加载(jvm的类加载器)此.class文件,此.class文件加载到内存之后,就是一个运行时类,存在缓存区,那么这个运行时类的自己就是一个class的实例java
在反射之前,如何建立一个类的对象,并调用其中的方法属性数组
public void test1() { Person p = new Person(); p.setAge(10); p.setName("AA"); p.show(); System.out.println(p); }
有了反射,能够经过反射建立一个类的对象,并调用其中的方法,下面详细说缓存
public void test2() throws Exception { Class clazz = Person.class; //1.建立clazz对应的运行时类Person类的对象 Person p = (Person)clazz.newInstance(); System.out.println(p); //2.经过反射调用运行时类的指定属性,public name的修改方式 Field f1 = clazz.getField("name"); f1.set(p, "LiuDaHua"); System.out.println(p); //private age的方式 Field f2 = clazz.getDeclaredField("age"); f2.setAccessible(true); f2.set(p, 20); System.out.println(p); //3.经过反射调用运行时类的指定方法 public修饰的 Method m1 = clazz.getMethod("show"); // 执行 m1.invoke(p); // 带参数的方法 Method m2 = clazz.getMethod("display", String.class); m2.invoke(p, "cn"); }
Class clazz = Person.class; System.out.println(clazz.getName()); Class clazz1 = String.class; System.out.println(clazz1.getName());
Person p = new Person(); Class clazz2 = p.getClass(); System.out.println(clazz.getName());
String className = "com.atguigu.java.Person"; Class clazz4 = Class.forName(className); System.out.println(clazz4);
ClassLoader classLoader = this.getClass().getClassLoader(); Class clazz5 = classLoader.loadClass(className); System.out.println(clazz5.getName());
整个代码jvm
public void test4() throws Exception { //1.调用运行时类自己的.class属性 Class clazz = Person.class; System.out.println(clazz.getName()); Class clazz1 = String.class; System.out.println(clazz1.getName()); //2.经过运行时类的对象获取 Person p = new Person(); Class clazz2 = p.getClass(); System.out.println(clazz.getName()); //3.经过Class的静态方法获取,经过此方式,体会反射的动态性 String className = "com.atguigu.java.Person"; Class clazz4 = Class.forName(className); System.out.println(clazz4); //4.经过类的加载器 ClassLoader classLoader = this.getClass().getClassLoader(); Class clazz5 = classLoader.loadClass(className); System.out.println(clazz5.getName()); }
一般直接使用类名.class , 例如Person.class测试
固然了,上面的几种方法都是能够的ui
String className = "com.atguigu.java.Person"; Class clazz = Class.forName(className);
建立对应的运行时类的对象,使用的是newInstance(),实际上就是运用了运行时类的空参数的构造器this
要想可以建立成功code
Object obj = clazz.newInstance();//调用的是空参构造器 Person p = (Person)obj; System.out.println(p);
所有代码对象
public void test1() throws Exception { // 获取Class实例 Class clazz = Person.class; //建立对应的运行时类的对象,使用的是newInstance(),实际上就是运用了运行时类的空参数的构造器 //要想可以建立成功,①要求对应的运行时类要有空参数的构造器,②构造器的权限修饰符的权限要足够 Object obj = clazz.newInstance();//调用的是空参构造器 Person p = (Person)obj; System.out.println(p); }
1.getFields() 返回 :表示公共字段的 Field 对象的数组,只能获取运行时类中以及父类中声明的为public的属性接口
Field[] fiels = clazz.getFields(); for(int i=0;i<fiels.length;i++) { System.out.println(fiels[i]); }
2.getDeclaredFields() :获取运行时类自己声明的全部的属性,包括私有的
Field[] fiels1 = clazz.getDeclaredFields(); for(int i=0;i<fiels1.length;i++) { System.out.println(fiels1[i].getName()); } //加强for循环 for(Field f:fiels1) { System.out.println(f.getName()); }
权限修饰符 变量类型 变量名
1.获取每一个属性的权限修饰符
Field[] field = clazz.getDeclaredFields(); for(Field i:field) { //1.获取每一个属性的权限修饰符 int a = i.getModifiers(); String str1 = Modifier.toString(a); System.out.print(str1+" "); }
2.获取属性的变量类型
Field[] field = clazz.getDeclaredFields(); for(Field i:field) { //2.获取属性的变量类型 Class type = i.getType(); System.out.print(type+" "); }
3.获取属性名
Class clazz = Person.class; Field[] field = clazz.getDeclaredFields(); for(Field i:field) { //3.获取属性名 System.out.print(i.getName()); System.out.println(); }
1.getMethods() 获取运行时类及其父类中全部声明为public的方法
Class clazz = Person.class; Method[] m1 = clazz.getMethods(); for(Method m:m1) { System.out.println(m); }
2.getDeclaredMethods() 获取运行时类自己声明的全部的方法
Method[] methods = clazz.getDeclaredMethods(); for(int i=0;i<methods.length;i++) { System.out.println(methods[i]); }
注解 权限修饰符 返回值类型 方法名 形参列表 异常
1.注解
Class clazz = Person.class; Method[] m1 = clazz.getMethods(); for(Method m:m1) { Annotation[] an = m.getAnnotations(); for(Annotation a:an) { System.out.println(a); } }
2.权限修饰符
int a = m.getModifiers(); String str1 = Modifier.toString(a); System.out.print(str1+" ");
3.返回值类型
Class return1 = m.getReturnType(); System.out.print(return1+" ");
4.方法名
System.out.print(m.getName()+" ");
5.形参列表
System.out.print("("); Class[] params = m.getParameterTypes(); for(Class p : params) { System.out.print(p.getName()); } System.out.println(")"+" ");
6.抛的异常
Class[] ex = m.getExceptionTypes(); for(Class e:ex) { System.out.print(e.getName()); } // for(int i=0;i<ex.length;i++) { // System.out.print(ex[i].getName()); // }
@Test public void test5() throws Exception { Class clazz = Class.forName("com.atguigu.java.Person"); Constructor[] cons = clazz.getDeclaredConstructors(); for(Constructor c : cons) { System.out.println(c); } }
@Test public void test6() { Class clazz = Person.class; Class super1 = clazz.getSuperclass(); System.out.println(super1); }
@Test public void test7() { Class clazz = Person.class; Type type1 = clazz.getGenericSuperclass(); System.out.println(type1); }
@Test public void test8() { Class clazz = Person.class; Type type1 = clazz.getGenericSuperclass(); ParameterizedType param= (ParameterizedType)type1; Type[] ars = param.getActualTypeArguments(); System.out.println((Class)ars[0]); }
@Test public void test9() { Class clazz = Person.class; Class[] i = clazz.getInterfaces(); for(Class a:i) { System.out.println(a); } }
@Test public void test10() { Class clazz = Person.class; Package p = clazz.getPackage(); System.out.println(p); }
所有代码以下:
package com.atguigu.java; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import org.junit.Test; /** * 经过反射获取类的完整结构 * * @author MD * */ public class TestField { /** * 1.获取运行时类的属性 */ @Test public void test1() { Class clazz = Person.class; //1.getFields() 返回 :表示公共字段的 Field 对象的数组 // 只能获取运行时类中以及父类中声明的为public的属性 // Field[] fiels = clazz.getFields(); // for(int i=0;i<fiels.length;i++) { // System.out.println(fiels[i]); // } //2.getDeclaredFields() :获取运行时类自己声明的全部的属性 Field[] fiels1 = clazz.getDeclaredFields(); for(int i=0;i<fiels1.length;i++) { System.out.println(fiels1[i].getName()); } //加强for循环 for(Field f:fiels1) { System.out.println(f.getName()); } } /** * 权限修饰符 变量类型 变量名 * 2.获取属性的各个部分的内容 * */ @Test public void tset2() { Class clazz = Person.class; Field[] field = clazz.getDeclaredFields(); for(Field i:field) { //1.获取每一个属性的权限修饰符 int a = i.getModifiers(); String str1 = Modifier.toString(a); System.out.print(str1+" "); //2.获取属性的变量类型 Class type = i.getType(); System.out.print(type+" "); //3.获取属性名 System.out.print(i.getName()); System.out.println(); } } /** * 3.获取运行时类的方法 */ @Test public void test3() { Class clazz = Person.class; //1.getMethods() 获取运行时类及其父类中全部声明为public的方法 // Method[] m1 = clazz.getMethods(); // for(Method m:m1) { // System.out.println(m); // } //2.getDeclaredMethods() 获取运行时类自己声明的全部的方法 Method[] methods = clazz.getDeclaredMethods(); for(int i=0;i<methods.length;i++) { System.out.println(methods[i]); } } /** * 4.获取方法的各个部分的内容 * 注解 权限修饰符 返回值类型 方法名 形参列表 异常 * */ @Test public void test4() { Class clazz = Person.class; Method[] m1 = clazz.getMethods(); for(Method m:m1) { //1.注解 Annotation[] an = m.getAnnotations(); for(Annotation a:an) { System.out.println(a); } //2.权限修饰符 int a = m.getModifiers(); String str1 = Modifier.toString(a); System.out.print(str1+" "); //3.返回值类型 Class return1 = m.getReturnType(); System.out.print(return1+" "); //4.方法名 System.out.print(m.getName()+" "); //5.形参列表 System.out.print("("); Class[] params = m.getParameterTypes(); for(Class p : params) { System.out.print(p.getName()); } System.out.println(")"+" "); //6.抛的异常 Class[] ex = m.getExceptionTypes(); for(Class e:ex) { System.out.print(e.getName()); } // for(int i=0;i<ex.length;i++) { // System.out.print(ex[i].getName()); // } System.out.println(); } } /** * 5.获取构造器 * @throws Exception */ @Test public void test5() throws Exception { Class clazz = Class.forName("com.atguigu.java.Person"); Constructor[] cons = clazz.getDeclaredConstructors(); for(Constructor c : cons) { System.out.println(c); } } /** * * 6.获取运行时类的父类 */ @Test public void test6() { Class clazz = Person.class; Class super1 = clazz.getSuperclass(); System.out.println(super1); } /** * 7.获取带泛型的父类 */ @Test public void test7() { Class clazz = Person.class; Type type1 = clazz.getGenericSuperclass(); System.out.println(type1); } /** * 8.获取父类的泛型 */ @Test public void test8() { Class clazz = Person.class; Type type1 = clazz.getGenericSuperclass(); ParameterizedType param= (ParameterizedType)type1; Type[] ars = param.getActualTypeArguments(); System.out.println((Class)ars[0]); } /** * 9.获取实现的接口 */ @Test public void test9() { Class clazz = Person.class; Class[] i = clazz.getInterfaces(); for(Class a:i) { System.out.println(a); } } /** * 10.获取所在的包 */ @Test public void test10() { Class clazz = Person.class; Package p = clazz.getPackage(); System.out.println(p); } }
1. 获取指定的属性
getField(String fieldName):获取运行时类中声明为public的指定的属性名为fieldName的属性
Field name = clazz.getField("name");
2.建立运行时类的对象
Person p = (Person) clazz.newInstance(); System.out.println(p);
3.将运行时类的指定属性赋值
name.set(p, "Jerry"); System.out.println(p);
给age赋值,private须要注意
getDeclareField(String fieldName):获取运行时类中指明为filedName的属性
Field age = clazz.getDeclaredField("age"); //因为属性权限修饰符的限制,为了保证能够给属性赋值,须要在操做前使得此属性可被操做 age.setAccessible(true);//私有的设置成能够访问的 age.set(p,1); System.out.println(p);
给id赋值,默认的修饰符
Field id = clazz.getDeclaredField("id"); id.set(p,10); System.out.println(p);
1.getMethod(String methodName,Class...params)获取指定的public方法,方法名,参数列表
Class clazz = Person.class; Method m1 = clazz.getMethod("show");
2.建立运行时类的对象
Person p =(Person)clazz.newInstance();
3.和属性类似,这里是invoke关键字里面是对象和参数列表,或许还有返回值,用Object接收
Object returnVal = m1.invoke(p); System.out.println(returnVal);//没返回值的打印为null
4.获取toString()有返回值的
Method m2 = clazz.getMethod("toString"); Object returnVal1 = m2.invoke(p); System.out.println(returnVal1);
5.获取display()带参数的
Method m3 = clazz.getMethod("display",String.class); m3.invoke(p, "china");
6.获取info()静态的方法
Method m4 = clazz.getMethod("info"); m4.invoke(Person.class);
7.获取Test() 私有的带参数的有返回值的
Method m5 = clazz.getDeclaredMethod("Test",String.class,Integer.class); m5.setAccessible(true); Object o = m5.invoke(p,"测试",5); System.out.println(o);
public void test3() throws InstantiationException, Exception { Class clazz = Person.class; Constructor cons = clazz.getDeclaredConstructor(String.class,int.class); cons.setAccessible(true); Person p = (Person)cons.newInstance("迪丽热巴",20); System.out.println(p); }
所有代码
package com.atguigu.java; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; /** * ******调用对应的运行时类的指定的结构(属性、方法) * @author MD * */ public class TestField1 { /** * 调用运行时类指定的属性 * @throws Exception * @throws NoSuchFieldException */ @Test public void test1() throws Exception { Class clazz = Person.class; //1.获取指定的属性 //getField(String fieldName):获取运行时类中声明为public的指定的属性名为fieldName的属性 Field name = clazz.getField("name"); //2.建立运行时类的对象 Person p = (Person) clazz.newInstance(); System.out.println(p); //3.将运行时类的指定属性赋值 name.set(p, "Jerry"); System.out.println(p); //给age赋值,private须要注意 //getDeclareField(String fieldName):获取运行时类中指明为filedName的属性 Field age = clazz.getDeclaredField("age"); //因为属性权限修饰符的限制,为了保证能够给属性赋值,须要在操做前使得此属性可被操做 age.setAccessible(true);//私有的设置成能够访问的 age.set(p,1); System.out.println(p); //给id赋值,默认的修饰符 Field id = clazz.getDeclaredField("id"); id.set(p,10); System.out.println(p); } /** * 调用运行时类中指定的方法 * @throws Exception * @throws NoSuchMethodException */ @Test public void test2() throws NoSuchMethodException, Exception { Class clazz = Person.class; //getMethod(String methodName,Class...params)获取指定的public方法,方法名,参数列表 Method m1 = clazz.getMethod("show"); //建立运行时类的对象 Person p =(Person)clazz.newInstance(); //和属性类似,这里是invoke关键字里面是对象和参数列表,或许还有返回值,用Object接收 Object returnVal = m1.invoke(p); System.out.println(returnVal); //获取toString()有返回值的 Method m2 = clazz.getMethod("toString"); Object returnVal1 = m2.invoke(p); System.out.println(returnVal1); //获取display()带参数的 Method m3 = clazz.getMethod("display",String.class); m3.invoke(p, "china"); //获取info()静态的方法 Method m4 = clazz.getMethod("info"); m4.invoke(Person.class); //获取Test() 私有的带参数的有返回值的 Method m5 = clazz.getDeclaredMethod("Test",String.class,Integer.class); m5.setAccessible(true); Object o = m5.invoke(p,"测试",5); System.out.println(o); } /** * 调用指定的构造器,建立类对象 * @throws Exception * @throws InstantiationException */ @Test public void test3() throws InstantiationException, Exception { Class clazz = Person.class; Constructor cons = clazz.getDeclaredConstructor(String.class,int.class); cons.setAccessible(true); Person p = (Person)cons.newInstance("迪丽热巴",20); System.out.println(p); } }
类加载器是用来把类(class)装载进内存
1.获取一个系统类加载器
ClassLoader loader1 = ClassLoader.getSystemClassLoader(); System.out.println(loader1);
2.获取系统类加载器的父类加载器,即扩展类加载器
ClassLoader loader2 = loader1.getParent(); System.out.println(loader2);
3.获取扩展类加载器的父类加载器,即引导类加载器,加载的是核心库,打印为null
ClassLoader loader3 = loader2.getParent(); System.out.println(loader3);
4.测试当前类由哪一个类加载器进行加载
Class clazz1 = Person.class; ClassLoader loader4 = clazz1.getClassLoader(); System.out.println(loader4);//系统类加载器
JVM中类的装载是由ClassLoader和它的子类来实现的,
Java ClassLoader 是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。