java之反射及类的加载

一、类的加载

1、定义:Java语言里,当程序要使用某个类时,如果该类还为被加载到内存,则系统会通过加载、连接、初始化三步来实现对这个类的初始化。类加载都是在程序运行期间完成的,这种策略虽然会令类加载时稍微增加一些性能开销,但是会给java应用程序提供高度的灵活性。
1.2、加载:将.class文件读入内存中,并为之创建一个Class对象;任何类被使用时系统都会建立一个Class对象。
1.3、验证:是否有正确的内部结构,并和其他 类协调一致。
     准备:负责为类的静态成员分配内存,并设置默认初始值。
     解析:将类的二进制数据中的符号引用替换成直接引用。
1.4、初始化:java会为类的基本类型的变量提供一个初始值,各类型初始值不同,非基本类型初始为null。注意,这里的变量必须是类变量,注意                 ,只会为类变量提供初始化,而局部变量不会。如果局部变量没有初始化,会收到一个出错信息。
2、类加载器分类:
根类加载器:java核心类的加载(如:System,String,在JDK中JRE的lib目录下rt.jar文件)
扩展类加载器:负责JRE的扩展目录中jar报的加载(JDK中JRE的lib目录ext文件)
系统加载器:在JVM中启动时加载来自java命令的class文件以及classpath环境变量所指定的jar包和类的路径

二、反射

1、定义:通过Class文件对象,使用该类文件中的成员变量、构造方法、成员方法。
2、反射机制的相关API
 
 
2.1、
import java.util.ArrayList;
import model.UserInfo;
public class Class类的获得 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//通过对象
		UserInfo ui =new UserInfo();
		Class c = ui.getClass();//Class类主要的功能能够将需要关注的某个
		//类型的所有信息都解析出来
		System.out.println(c);
		//通过类名,必须是完整的,包含包的
		//ArrayList al =new ArrayList();
		try {
			Class c1 = Class.forName("java.util.ArrayList");
			System.out.println(c1);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println(e.getMessage());
			e.printStackTrace();
		}			
	}
}
2.2、得到构造方法和方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import model.UserInfo;
public class 得到构造方法和方法 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//构造方法Constructor
		UserInfo ui = new UserInfo();
		Class c=ui.getClass();
		Constructor[] cArr = c.getConstructors();
		System.out.println("系统提供默认的构造方法"+cArr.length);
		//方法method
		System.out.println("显示类里面的方法");
		Method[] mArr = c.getMethods();
		for(Method m:mArr){
			System.out.println(m.getName());
		}
	}
}
2.3、得到属性
import java.lang.reflect.Field;
public class 得到属性 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//根据字符串得到某个类所有的属性
		String className = "model.UserInfo";
		//通过Class类型对象才可以
		try {
			Class c = Class.forName(className);
			//利用Class对象得到所有的fields信息(属性信息)
			Field[] farr = c.getFields();//这个方法只能够显示非private的属性
			farr = c.getDeclaredFields();//这个属性可以得到包括访问权限为private的
			//正确得到属性的标志,能够显示出属性名
			//遍历属性数组
			System.out.println("下面显示属性名");
			for(Field f:farr){
				System.out.println(f.getName());
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
2.4、得到一个的类型
import java.util.Date;
public class 得到一个的类型 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//直接根据类名得到Class对象
		System.out.println(Integer.class);
		System.out.println(String.class);
		System.out.println(Thread.class);
		System.out.println(Date.class);
	}
}
2.5、调用有参的构造方法得到实例
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class 调用有参的构造方法得到实例 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//如何证明利用有参的创建用户对象成功,直接打印出这个对象即可
		//得到Class 对象
		try {
			Class clazz = Class.forName("model.UserInfo");
			//得到构造方法对象
			Constructor c = clazz.getConstructor(Integer.class,String.class);
			Object obj =c.newInstance(1,"admin");
			System.out.println(obj);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
2.6、
反射调用有参有返回值
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class 反射调用有参有返回值 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String className = "model.UserInfo";
		String methodName = "getSalary";
		//
		try {
			Class clazz = Class.forName(className);
			Object user = clazz.newInstance();//创建对象的另外一种方式
			//得到方法
			Method m = clazz.getMethod(methodName, int.class,double.class,String.class);
			Object sal = m.invoke(user, 3,4500,"");
			System.out.println(sal);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
2.7、反射调用有返回值无参的方法
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class 反射调用有返回值无参的方法 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 
		String className = "model.UserInfo";
		String methodName = "getSalary";
		//得到Class对象
		try {
			Class clazz = Class.forName(className);
			//得到有参的构造方法对象
			Constructor c=clazz.getConstructor(Integer.class,String.class);
			Object userInfo = c.newInstance(3,"aaa");
			//最终要执行的getSalary方法
			//创建method对象
			Method m=clazz.getMethod(methodName);
			Object sal = m.invoke(userInfo);
			System.out.println(sal);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
2.8、利用反射得到实例
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class 利用反射得到实例 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//利用包含有类名的 字符串,创建出对象
		String className = "model.UserInfo";
		try {
			Class c = Class.forName(className);
			//先得到构造方法对象,利用构造方法对象的newInstance方法创建出实例
			Constructor constructor=c.getConstructor();
			
			//利用构造方法对象的newInstance()创建出userInfo实例
			Object obj = constructor.newInstance();
			System.out.println(obj);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
2.9、通过反射调用无参无返回值方法
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class 通过反射调用无参无返回值方法 {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String className = "model.UserInfo";
		String mName = "show";
		//得到Class对象
		try {
			Class clazz = Class.forName(className);
			 
			//创建出有参的构造方法对象
			Constructor c = clazz.getConstructor(Integer.class,String.class);
			//创建出userinfo对象
			Object obj = c.newInstance(2,"cyd");
			clazz.newInstance();
			//创建Method对象
			Method m = clazz.getMethod(mName);
			//调用方法,
			//m.invoke(clazz,null);
			m.invoke(obj);//method的invoke的第一个参数,是告诉method对象要利用哪个对象执行指定的方法
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
2.10、专业方法得到getset

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class 专业方法得到getset {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//首先用反射生成UserInfo对象,调用的是有参的构造方法
		String className = "model.UserInfo";	
		try {
			Class clazz = Class.forName(className);
			System.out.println(clazz.getSimpleName());
			Constructor c = clazz.getConstructor(Integer.class, String.class);
			Object userInfo = c.newInstance(3, "aaa");
			//通过get方法显示出所有属性的值
			//得到属性对象
			Field[] fields = clazz.getDeclaredFields();
			//遍历fields
			for(Field f:fields){
				PropertyDescriptor pd = new PropertyDescriptor(f.getName(),clazz);
				//利用pd对象得到get对象
				Method getMd= pd.getReadMethod();
				System.out.println("属性名:"+f.getName()+"属性值"+getMd.invoke(userInfo));
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 得到有参的构造方法对象
		catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

3、反射的运用:
3.1、通过反射运行配置文件中的内容,代码如下:
以下是class.txt文件
className=
methodName=
以下是java文件代码
package reflection;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Reflection1 {
	/**
	 * @param args
	 * @throws IOException 
	 * @throws ClassNotFoundException 
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws IllegalArgumentException 
	 */
	public static void main(String[] args) throws IOException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
		//加载键值对数据
		Properties prop = new Properties();
		FileReader fr = new FileReader("class.txt");
		prop.load(fr);
		fr.close();
		//数据获取
		String className= prop.getProperty("className");
		String methodName=prop.getProperty("methodName");
		//反射
		Class c= Class.forName(className);
		Constructor con = c.getConstructor();
		Object obj = con.newInstance();
		//调用方法
		Method method= c.getMethod(methodName);
		method.invoke(obj);
	}
}
3.2、通过反射越过泛型检查
package reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class reflection2 {
	/**
	 * @param args
	 * @throws NoSuchMethodException 
	 * @throws SecurityException 
	 * @throws InvocationTargetException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		ArrayList<Integer> arrayList = new ArrayList<Integer>();
		Class class1 = arrayList.getClass();
        Method method= class1.getMethod("add", Object.class);
        method.invoke(arrayList, "hello");
        System.out.println(arrayList);
	}
}
3.3、通过反射设置某对象的某个属性值为固定植

package reflection;
import java.lang.reflect.Field;
/**
 * 此为工具类
 * @author zxn
 *
 */
public class Tool {
	public void setProperty(Object obj,String propertyName,Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
		//根据对象获取字节马文件对象
		Class class1 = obj.getClass();
		//获取该对象的propertyName成员变量
		Field declaredField = class1.getDeclaredField(propertyName);
		//取消访问检查
		declaredField.setAccessible(true);
		//给对象的成员变量赋值
		declaredField.set(obj, value);
	}
}


package reflection;
public class ToolDemo {
	/**
	 * 此为实现类
	 * @param args
	 * @throws IllegalAccessException 
	 * @throws NoSuchFieldException 
	 * @throws IllegalArgumentException 
	 * @throws SecurityException 
	 */
	public static void main(String[] args) throws SecurityException, IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
		Person person=new Person();
		Tool tool = new Tool();
		tool.setProperty(person,"name","庄学南");
		tool.setProperty(person, "age", 26);
        System.out.println(person);
	}
}
class Person{
	private String name;
	public int age;
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}	
}

谢言:


欢迎各位观看者评论指导。如果喜欢可以顶下,或者关注我!





  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值