类加载器、反射技术、动态代理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/xuruanshun/article/details/102683578

目录

1.类加载器(ClassLoader)

2.反射

3.动态代理


 

1.类加载器(ClassLoader)

1.1.概述

1.2.类加载的时间

1.3.​​​​​​​使用类加载器管理配置文件

2.反射

​​​​​​​2.1.反射概述

反射依赖于一个东西Class类Class类是反射的基石

扫描二维码关注公众号,回复: 7658718 查看本文章

 

​​​​​​​2.1.1.Class类介绍

​​​​​​​2.1.2.获取Class的三种方式

/*
 * 演示:
  获取Class对象的方式
 * 	方式1:类名.class
 * 	方式2:对象.getClass()
 * 	方式3:static Class forName(String className) 根据类的名称获取Class对象,注意此处的类名必须是全称

 * 获取类的信息:
 * 	 String getSimpleName():获取类名全称(java.lang.String)  
 * 	 String getName():获取类名简称(String)
 * 
 * 注意:一个类,在内存中只会有1份字节码文件对象!

 * 我们应该用哪一种?
 * 	如果是自己玩,就用前两种,这两种使用时,都需要先知道具体的数据的类型
 * 	如果是开发,一般用第三种。第三种比前两张扩展性更好
 */
public class ClassDemo {
	public static void main(String[] args) throws ClassNotFoundException {
		// 方式1:类名.class
		Class clazz1 = String.class;
		System.out.println(clazz1.getSimpleName());// String
		System.out.println(clazz1.getName());// java.lang.String
		System.out.println("---------------------------");
		// 方式2:对象.getClass();
		Class clazz2 = "hello".getClass();
		System.out.println(clazz2.getSimpleName());// String
		System.out.println(clazz2.getName());// java.lang.String
		System.out.println("---------------------------");
		// 方式3:static Class forName(String className) 根据类的名称获取Class对象
		// Class clazz3 = Class.forName("String");//类名必须是全称 
		Class clazz3 = Class.forName("java.lang.String");
		System.out.println(clazz3.getSimpleName());
		System.out.println(clazz3.getName());
		System.out.println("---------------------------");
		
		System.out.println(clazz1 == clazz2);//true
		System.out.println(clazz1 == clazz3);//true
	}
}

​​​​​​​2.1.3.预定义对象:

/*
 * 演示:9种预定义对象
 * 	包含了8种基本数据类型,以及一个void
 * 	9种预定义对象,也被称为原始类型:
 * 	判断是否是原始类型:isPrimitive()
 * 	判断是否是数组:Class.isArray()
 * 
 * 注意:任何一个包装类的静态成员变量:TYPE 都表示其对应基本类型的字节码对象
 */
public class ClassDemo02 {
	public static void main(String[] args) {
		Class int_clazz = int.class;
		System.out.println(int_clazz);// int
		System.out.println(char.class);// char
		System.out.println(boolean.class);// boolean
		System.out.println("------------------------");

		Class integer_clazz = Integer.class;
		System.out.println(int_clazz == integer_clazz);// false
		System.out.println(int_clazz == Integer.TYPE);// true
		System.out.println("------------------------");

		Class void_clazz = void.class;
		System.out.println(void_clazz);//void
		System.out.println("------------------------");
		
		System.out.println(int_clazz.isPrimitive());//true
		System.out.println(void_clazz.isPrimitive());//true
		System.out.println(integer_clazz.isPrimitive());//false
		System.out.println("------------------------");

		Class arr_clazz = int[].class;
		System.out.println(arr_clazz);//class [I
		System.out.println(arr_clazz.isPrimitive());//false
		System.out.println(arr_clazz.isArray());//true
	}
}

​​​​​​​2.1.4.反射的概念

​​​​​​​2.2.使用反射获取构造函数(Constructor)

/*
 * 演示:反射获取构造函数
 * 	Constructor[] getConstructors() 获取所有公共的构造函数
 * 	Constructor[] getDeclaredConstructors() 获取所有构造函数
 * 	Constructor getConstructor(Class ... parameterTypes) 根据参数列表获取某个公共的构造函数
 * 	Constructor getDeclaredConstructor(Class ... parameterTypes) 根据参数列表获取某个任意的构造函数

 * 获取构造函数有什么用?用来创建对象!
 * 	 Object newInstance(Object... initargs):创建对象,参数为相匹配的实际参数
 * 
 * 对于私有的成员,必须开启暴力模式:
 * 	setAccessible(true)
 */
public class ClassDemo03 {
	public static void main(String[] args) throws Exception {
		Class clazz = File.class;
        //获取多个构造函数
		//Constructor[] getConstructors() 获取所有公共的构造函数
//		Constructor[] cs = clazz.getConstructors();
		//Constructor[] getDeclaredConstructors() 获取所有构造函数
//		Constructor[] cs = clazz.getDeclaredConstructors();
        //遍历构造函数
//		for( Constructor c : cs){
//			System.out.println(c);
//		}
	
        //获取单个构造函数
		//Constructor getConstructor(Class ... parameterTypes) 根据参数列表获取某个公共的构造函数
		//需求:获取File(String pathname)
//		Constructor c = clazz.getConstructor(String.class);
//		System.out.println(c);
		// Constructor getDeclaredConstructor(Class ... parameterTypes) 根据参数列表获取任意构造函数
		// 需求:获取私有构造:File(String child, File parent)
		Constructor c = clazz.getDeclaredConstructor(String.class,File.class);
//		System.out.println(c);
		// 设置暴力访问
		c.setAccessible(true);
		// Object newInstance(Object... initargs)
		File f = (File) c.newInstance("柳岩.jpg",new File("D:\\test"));// java.lang.IllegalAccessException:
		System.out.println(f.getAbsolutePath());
				
		// Class类中的功能: newInstance() 使用类的空参构造创建对象
		Class clazz2 = String.class;
		String s = (String) clazz2.newInstance();
		System.out.println(s.length());// 0
	}
}

​​​​​​​2.3.反射获取成员变量(Field)

/*
 * 演示:反射获取成员变量
 * Field[] getFields() 获取所有公共的成员变量
 * Field[] getDeclaredFields() 获取所有的成员变量
 * Field getField(String name) 根据变量名获取某个公共成员变量
 * Field getDeclaredField(String name) 根据变量名获取某个任意成员变量
 * 
 * 拿到成员有什么用?是用来获取对象中的数据
 * 	Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。 
 * 	void set(Object obj, Object value)  将指定对象变量上此 Field 对象表示的字段设置为指定的新值 
 * 
 * 注意:如果是静态成员,对象obj可以写null
 * 
 * 获取成员变量的类型:
 * 	Class getType()  返回该字段所声明的数据类型
 */
public class ClassDemo04 {
	public static void main(String[] args) throws Exception {
		Person p = new Person("柳岩", 21, "5216");
		Class clazz = p.getClass();
		// Field[] getFields() 获取所有公共的成员变量
//		Field[] fs = clazz.getFields();
		
		// Field[] getDeclaredFields() 获取所有的成员变量
//		Field[] fs = clazz.getDeclaredFields();
//		for(Field f : fs){
//			System.out.println(f);
//		}
		
		// Field getField(String name) 根据变量名获取某个公共成员变量
		Field f1 = clazz.getField("age");
//		System.out.println(f1);// public int cn.itcast.demo02.Person.age
		
		// Field getDeclaredField(String name) 根据变量名获取某个任意成员变量
		Field f2 = clazz.getDeclaredField("addr");
//		System.out.println(f2);// private java.lang.String cn.itcast.demo02.Person.addr
		
		// Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。 
		System.out.println(f1.get(p));// 21
		// 设置暴力访问
		f2.setAccessible(true);
		System.out.println(f2.get(p));
		
		
		// void set(Object obj, Object value)  将指定对象变量上此 Field 对象表示的字段设置为指定的新值 
		f2.set(p, "5416");
		
		System.out.println(f2.get(p));
		
		System.out.println("--------------------");
		
		System.out.println(f1.getType());// int
		
		System.out.println(f1.getType() == int.class);// true
		
		System.out.println(f2.getType() == String.class);// true
	}
}

2.4.​​​​​​​反射获取成员方法

/*
 * 演示:反射获取成员方法:
 * Method[] getMethods() 获取所有公共的成员方法,包括继承自父类的方法。
 * Method[] getDeclaredMethods() 获取自己声明的所有成员方法
 * Method getMethod(String name, Class ... parameterTypes) 根据方法名称及参数列表获取某个公共的成员方法
 * Method getDeclaredMethod(String name, Class ... parameterTypes) 根据方法名称及参数列表获取任意的成员方法
 * 
 * 获取Method有什么用?当然是拿来调用的。执行Method
 * 	String getName()  以 String 形式返回此 Method 对象表示的方法名称 
 * 执行一个Method:
 * 	Object invoke(Object obj, Object... args) 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法 
 * 		obj : 要调用的指定对象
 * 		args : 此Method所表示的方法的真实参数
 * A:非静态的有参方法
 * 	invoke时传递的参数必须和获取Method时传递的参数类型匹配
 * B:静态方法
 * 	在执行invoke时,第一个参数obj可以传null
 * C:无参方法
 * 	获取Method时,参数类型是可变参数,因此可以不写
 * 	执行invoke时,参数列表也是可变参数,因此也可以不写
 */
public class ClassDemo05 {
	public static void main(String[] args) throws Exception {
		Class clazz = String.class;
		// Method[] getMethods() 获取所有公共的成员方法
//		Method[] ms = clazz.getMethods();
//		for( Method m : ms){
//			System.out.println(m);
//		}
//		System.out.println("--------------------");
//		System.out.println(ms.length);// 72
		
		// Method[] getDeclaredMethods() 获取所有成员方法
//		Method[] ms = clazz.getDeclaredMethods();
//		for( Method m : ms){
//			System.out.println(m);
//		}
//		System.out.println("--------------------");
//		System.out.println(ms.length);// 73
		
		// Method getMethod(String name, Class ... parameterTypes) 根据方法名称及参数列表获取某个公共的成员方法
		// 获取一个方法:char charAt(int index) 
		Method m = clazz.getMethod("charAt", int.class);
//		System.out.println(m);// public char java.lang.String.charAt(int)
//		System.out.println(m.getName());//charAt
		
		// 演示:非静态的、带返回值的、有参方法。
		// 需求:执行charAt方法
		// 方式1:非反射方式执行:
		String str = "hello";
		char c = str.charAt(2);
		System.out.println(c);// l
		
		// 方式2:反射执行
		// Object invoke(Object obj, Object... args)
		char c2 = (char) m.invoke(str, 2);
		System.out.println(c2);// l
		
		// 演示:静态,有参方法
		// static String valueOf(double d) 
		Method m2 = clazz.getMethod("valueOf", double.class);
		String s = (String) m2.invoke(null, 12.34);
		System.out.println(s.length());// 5
		
		// 演示:无参无返回值方法
		// 获取show方法
		Person p = new Person();
		Class p_clazz = p.getClass();
		Method m3 = p_clazz.getMethod("show");
		m3.invoke(p);//  show ..... run
	}
}

 

 

 

​​​​​​​2.5.应用举例:

3.动态代理

猜你喜欢

转载自blog.csdn.net/xuruanshun/article/details/102683578