一、类的加载
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 + "]";
}
}
谢言:
欢迎各位观看者评论指导。如果喜欢可以顶下,或者关注我!