天天看点

黑马程序员——反射、类加载器

                                    ------- android培训、java培训、期待与您交流! ----------

属性的反射------Field

Student student = new Student("zs",1);
Field name = student.class.getField("name"); //不能获取private的,这里获取的只是类的属性,并不是具体某个对象的值。
Field age = student.class.getDeclaredField("age");//可以获取private的
name.setAccessible(true);暴力发射,强制去取某个对象的具体属性值。
name.getField(student);//具体获取student对象的name属性。

Constructor ms = Class.forName("StringDemo.Student").getDeclaredConstructor();
		
ms.setAccessible(true);
Student s = (Student) ms.newInstance(null);

Student ss = new Student("zs",21);
Field f = ss.getClass().getDeclaredField("name");//获取private的属性,这里只是获取类成员,并不是具体对象值。
f.setAccessible(true);//暴力反射
System.out.println(f.get(ss));//这里才是真正的获取具体对象的name值。

Field f1 = ss.getClass().getDeclaredField("age");
AccessibleObject[] array = new AccessibleObject[]{f1};//封装一个AccessibleObject数组,在下面调用静态发方法,一次对多个对象暴力反射

AccessibleObject.setAccessible(array, true);//对多个对象暴力反射
System.out.println(f1.get(ss));

Method-------------成员方法反射。方法是属于类的,跟对象没关系。
Method methods = String.class.getMethod("charAt",int.class);//获取charAt方法,后面是参数。
System.out.println(methods);
System.out.println(methods.invoke("absdfsf+fdfdf",4));//对应上面获取的methods方法,因为该方法有2个参数,所以这里传递两个参数
System.out.println(methods.invoke(null,3));//如果这里是null那么说明这个方法是静态方法,不需要对象。

Method zs = Math.class.getMethod("max", int.class,int.class);
System.out.println(zs.invoke(null, 3,4));

反射main方法-------------
Method  m = TT.class.getMethod("main", String[].class);
m.invoke(null, new Object[]{new String[]{"111"}});
m.invoke(null, (Object)new String[]{"111"});


数组的反射----------------
if(arr1.getClass().isArray()){
	for(int i =0 ;i<arr1.length;i++){
			System.out.println(arr1[i]);//由于数组是Object的类型的
			System.out.println(arr1[i].getClass().getName());//要获取每一个数组中每一个元素的类型。
		}
	}

判断一个对象是是否属于某个类的实例
1、用instancof关键字
2、用反射 obj.getClass.equals(Object.class);                

加载properties文件。

new Properties().load(new FileInputStream("dfdf.properties"));

类加载器------classLoader~~~~~~~~~3个类加载器   {BootStrap}第一个加载器,jvm虚拟机内核启动就加载  C++写的      ExtClassLoader   AppClassLoader

BootStrap---->第一个加载器,负责JRE/LIB/RT.JRA的加载

ExtCloassLoader---->第二个加载器,负责ext目录下面的jar文件加载

AppClassLoader----->第三个加载器,负责CLASSPATH环境变量下面的文件加载。

Properties properties = new Properties();
InputStream in  = Demo.class.getClassLoader().getResourceAsStream("resources/zs.properties");
p.load(in);
System.out.println(p.get("zs"));


//sun.misc.Launcher$AppClassLoader加载器 加载的
System.out.println(Demo.class.getClassLoader().getClass().getName());


//java.lang.NullPointerException 不代表没有加载器,他有一个特殊的加载器由C++写的BootStrap加载的
System.out.println(System.class.getClassLoader().getClass().getName());


//BootStrap---->ExtClassLoader------>AppClassLoader
ClassLoader classLoader = Demo.class.getClassLoader();
for(;classLoader!=null;){
System.out.println(classLoader.getClass().getName());
classLoader = classLoader.getParent();
}                

类加载器的委托机制-----------------------

每个类在被类加载器加载的时候,会先去找上级类加载器去加载。

先是2号加载器发启加载某个类,2号回去找他的父亲1号加载器来加载,如果一号有就加载

如果1号没有,那么2号加载器就自己去自己的管辖范围内找,如果2号加载器也没有找到

就会抛出异常ClassNotFoundException,并不会给他的孩子3号去找。

自定义类加载器------------

继承ClassLoader  重写  findClass方法 传入一个字节码  用提供的方法 解析

转载于:https://my.oschina.net/u/158350/blog/106795