java中类的加载、反射、动态代理、枚举

——<a href="" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! ——-类的加载、反射、动态代理、枚举

一.类的加载当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。1.加载:就是指将class文件读入内存,并为之创建一个Class对象★★任何类被使用时系统都会建立一个Class对象2.连接:验证 是否有正确的内部结构,并和其他类协调一致准备 负责为类的静态成员分配内存,并设置默认初始化值解析 将类的二进制数据中的符号引用替换为直接引用3.初始化:先是静态初始化,后是成员变量初始化4.类的初始化时机创建类的实例访问类的静态变量,或者为静态变量赋值调用类的静态方法使用反射方式来强制创建某个类或接口对应的java.lang.Class对象初始化某个类的子类直接使用java.exe命令来运行某个主类5.类的加载器:负责将.class文件加载到内存中,并为之生成对应的Class对象。虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。类加载器的组成:Bootstrap ClassLoader 根类加载器(核心类库)Extension ClassLoader 扩展类加载器(工具插件类)Sysetm ClassLoader 系统类加载器(我们自定义类)类加载器的作用:Bootstrap ClassLoader 根类加载器:也被称为引导类加载器,,负责Java核心类的加载,比如System,String等。在JDK中JRE的lib目录下rt.jar文件中。Extension ClassLoader 扩展类加载器:负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录。System ClassLoader 系统类加载器:负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。二.反射1.反射的概述JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.2.获取的Class对象的三种方式:1).使用对象,调用getClass();它是Object类中的方法。此方法是普通方法,不是静态的,要通过类的对象的引用去调用。Student stu = new Studetn();Class stuClass = stu.getClass();2).静态的class属性;任何的"数据类型"都有一个"静态的属性"–class属性,这个属性可以获取这个类的Class对象int.class;Class stuClass2 = Student.class;3).Class类forName()方法;用Class类中的静态方法forName()可以获取某个类的Class对象;public static Class forName(String className)这里的classname是一个全名限定的类名,也就是带包名的。Class stuClass3 = Class.forName("cn.itcast.demo01_获取Class对象的三种方式.Student"); 注意:在运行期间,一个类,只有一个Class对象产生。也就是说无论哪种方式获取的class对象都是同一个对象。三:通过反射获取和使用构造方法和类中成员变量即成员方法1.获取构造方法:使用的都是class类中的方法批量获取:public Constructor<?>[] getConstructors():获取所有公有的构造方法;返回一个包含某些 Constructor 对象引用的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法范例for(Constructor c : conArray ){★★System.out.println(c);}//打印出来的就是构造方法名称,如:public cn.itcast.demo02_通过Class获取某个类的的构造方法并调用.Student(boolean)public Constructor<?>[] getDeclaredConstructors():获取所有的构造方法。包括公有,受保护,默认,私有的构造方法。获取单个:public Constructor<T> getConstructor(Class<?>… parameterTypes):获取的有参数的公有的构造方法。parameterTypes 构造方法形参的类型的Class对象。范例:Constructor con2 = stuClass.getConstructor(boolean.class);public Constructor<T> getDeclaredConstructor(Class<?>… parameterTypes):获取指定的构造方法。可以是私有的。2.调用构造方法:使用Constructor中的方法public T newInstance(Object… initargs):使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例。谁调用此方法就使用那个构造方法创建一个对象。也就是返回的是一个类的对象,而所传的参数就是调用构造方法所用的实际参数。范例:obj = con2.newInstance(true);System.out.println("obj = " + obj);//obj = cn.itcast.demo02_通过Class获取某个类的的构造方法并调用.Student@1f82982//由于要访问是私有成员,所以这里要设置"取消访问限制检查",进行暴力访问public void setAccessible(boolean flag),Constructor的父类AccessibleObject中的方法,取消访问检查。可以用来访问类中的私有成员 3.获取成员属性:class类中的方法批量获取:public Field[] getFields():获取所有公有的成员变量public Field[] getDeclaredFields():获取所有的属性。包括私有的获取单个:public Field getField(String name):获取公有的指定属性范例:Field f = stuClass.getField("stuName");★★System.out.println(f);//打印的是是属性名,而不是值。★★public Field getDeclaredField(String name):获取指定属性。可以是私有的。4.获取、设置属性值:Field类中的方法public void set(Object obj,Object value):注意:设置前,一定要先实例化一个此类的对象。参数:obj – 应该修改其字段的对象,也就是此字段所在类的对象;value – 正被修改的 obj 的字段的新值。public object get(Object obj):获取字段的值,参数就是字段所在的类的对像,从中提取所表示字段的值的对象 。范例://先实例化出一个Student对象Object stuObj = stuClass.getConstructor().newInstance();//为字段设置值f.set(stuObj, "张学友");//获取字段的值:System.out.println("获取字段的值:" + f.get(stuObj));对于私有的属性,要经行包里访问。public void setAccessible(boolean flag),Field类对象.setAccessible(true);5.获取成员方法:class类中的方法批量获取:public Method[] getMethods() :获取所有的"公有"方法.并且从父类继承的方法也有★★★public Method[] getDeclaredMethods() :获取所有方法,包括私有的。范例:for(Method m : methodArray){System.out.println(m);打印的是方法名称(带参数类型)show(int)★★获取单个:public Method getMethod(String name, Class<?>… parameterTypes) :获取某个公有的方法。 形参:name:方法名; parameterTypes:形参的类型列表,可变参数public Method getDeclaredMethod(String name, Class<?>… parameterTypes):获取某个方法。可以是私有的。6.访问成员方法:Method类中方法注意:调用方法前,一定要先实例化一个此类对象public Object invoke(Object obj,Object… args);object就是使用args实参后方法的返回值,★★参数:obj : 方法所属的对象;args: 调用方法需要的实参同样暴力访问public void setAccessible(boolean flag)method对象.setAccessible(true)四.反射的重要应用:1.通过反射运行配置文件的内容public class Demo {public static void main(String[] args) throws Exception{/*//获取一个class类对象,使用三种方法中那一中,class类中静态方法Class aclass =Class.forName("cn.itcast.Test反射读取配置文件.line2");//由获得Class对象再得到一个该类的一个对象Object obj=aclass.getConstructor().newInstance();//得到的该类的一个成员方法Method m=aclass.getMethod("move", int.class);m.invoke(obj, 20);*///定义一个class类对象Class aclass=Class.forName(getvalue("classname"));//通过反射,并调用构造方法,创建一个该类的对象Object obj=aclass.getConstructor(String.class).newInstance("好方法");//通过反射调用其成员方法aclass.getMethod(getvalue("methodname"), int.class).invoke(obj, 50);}//通过定义一个方法来获取几种东西public static String getvalue(String str)throws IOException{//定义一个properties集合map集合,以便于读写文件Properties pro=new Properties();//定义一个输入流FileReader filein=new FileReader(new File("pro.properties"));//读取文件中内容到集合中pro.load(filein);//关闭资源filein.close();return pro.getProperty(str);}}public class line2 {private String name;public line2(String name){this.name =name;}public void move(int n){System.out.println("名字是:"+name+"小伙的年龄是"+n);}}2.通过泛型越过泛型检查泛型只是在编译期间有作用,可以通过泛型直接加载其class,往声明泛型的集合添加东西public class Demo {public static void main(String[] args) throws Exception {//定义一个集合ArrayList<Integer> list=new ArrayList<>();list.add(10);//使用反射创建此类的class对象,调用其方法Class aclass=ArrayList.class;//list.getclass();//获取其方法的对象,使用的参数为object.class,通用的类型Method m=aclass.getMethod("add", Object.class);m.invoke(list, "nihaoma ");System.out.println(list);}}3.通过泛型设置某个对象的某个属性为指定值public class Demo {public static void main(String[] args) throws Exception {Cat c=new Cat();setValue(c,"name","bosimao");setValue(c, "age", 2);System.out.println("年龄:"+c.getAge()+"名字:"+c.getName());}private static void setValue(Object obj, String fieldName, Object value) throws Exception {Class aclass=obj.getClass();Field field=aclass.getDeclaredField(fieldName);//由于是私有属性,需要暴力访问field.setAccessible(true);field.set( obj, value);}}public class Cat {private String name;private int age=0;public String getName(){return this.name;}public int getAge(){return this.age;}}五.动态代理1.动态代理的概述本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。美文、不要轻易用过去来衡量生活的幸与不幸!

java中类的加载、反射、动态代理、枚举

相关文章:

你感兴趣的文章:

标签云: