分析简单java类与反射的联系
web对反射的操作支持
在JSP之中有一种技术--javaBean。而且在jsp里面也配套有相应的操作方式,javaBean的核心在于简单java类,于是下面演示此操作
代码示例:创建一个简单的Student类
package com.hbsi.domain;
public class Student {
public Student() {
System.out.println("构造方法执行了,对象实例化");
}
private String name;
private Integer age;
private String sex;
public String getName() {
System.out.println("getName被调用");
return name;
}
public void setName(String name) {
System.out.println("setName被调用");
this.name = name;
}
public Integer getAge() {
System.out.println("getAge被调用");
return age;
}
public void setAge(Integer age) {
System.out.println("setAge被调用");
this.age = age;
}
public String getSex() {
System.out.println("getSex被调用");
return sex;
}
public void setSex(String sex) {
System.out.println("setSex被调用");
this.sex = sex;
}
}

 在web项目中所建立的每个java类最终都会保存在WEB-INF/classes目录下,所以classes就是一个CLASSPATH。但是要求是:

建立一个表单,输入完成后的数据需要设置到Student类中,同时再通过Student类对象取得输入内容
代码范例:定义一个输入表单
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>student_insert.jsp</title>
</head>
<body>
<h1>纯菜鸟</h1>
<form action="student_insert_do.jsp" method="post">
姓名:<input type="text" name="name"><br/>
年龄:<input type="text" name="age"><br/>
性别:<input type="text" name="sex"><br/>
<input type="submit" value="确定">
<input type="reset"><br/>
</form>
</body>
</html>

 此时Student类已经生成了对应的setter 和 getter方法,同时表单中的参数名与Student中的属性名一致,

代码范例:按照传统方式编写一个接受页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.hbsi.domain.Student"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
Student stu = new Student();
stu.setName(request.getParameter("name"));
stu.setAge(Integer.parseInt(request.getParameter("age")));
stu.setSex(request.getParameter("sex"));
%>
<h1>Name:<%=stu.getName()%></h1>
<h1>Age :<%=stu.getAge() %></h1>
<h1>Sex :<%=stu.getSex() %></h1>
</body>
</html>

 将此项目放到Tomcat中并且运行项目并输入,“懒蛋,18,男”执行结果如下

但是如果直接使用JSP的开发方式,以上的代码就可以简化了
代码范例编写简化后的JSP页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.hbsi.domain.Student"%>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="stu" class="com.hbsi.domain.Student" scope="page"/>
<jsp:setProperty property="*" name="stu"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
%>
<h1>Name:<jsp:getProperty property="name" name="stu"/></h1>
<h1>Age :<jsp:getProperty property="age" name="stu"/></h1>
<h1>Sex :<jsp:getProperty property="sex" name="stu"/></h1>
</body>
</html>

 执行程序并输入“懒蛋,19,jj” 运行结果如下

下面来看一下使用到的三个标签
1. 定义javaBean对象:
<jsp:useBean id="stu" class="com.hbsi.domain.Student" scope="page"/>
1. id:表示定义的实例化名字,Student stu = new Student();
2. class:对象的类型。此处是依靠反射实例化对象;(调用无参构造)
3. scope:此对象的保存范围:page,request,session,application
2. 设置属性内容:
<jsp:setProperty property="*" name="stu"/>
1. name:表示的要操作的对象名称,与id相同
2. property:要操作的属性名称,如果为* 表示自动操作,也可以指定,例如
<jsp:setProperty property="name" name="stu"/>
表示只操作name的赋值,参数名称一定要与属性名称一致(setter)
3. 取得属性内容:
<jsp:getProperty property="name" name="stu"/>
1. name:表示的要操作的对象名称,与id相同
2. property:取得输出的属性内容(getter)
但是此时的控制柜台就输出了
构造方法执行了,对象实例化
setName被调用
setAge被调用
setSex被调用
getName被调用
getAge被调用
getSex被调用
在Servlet之中自定义反射接收
对于WEB而言,发现“<jsp:useBean>”等标签只能在JSP页面使用,但是如果是一个真正开发,一定是使用Servlet进行的,所以现在就希望编写一个与之类似的功能,可以帮助我们实现此类操作。
本程序继续使用之前的Student类与student_insert.jsp页面,先完成一个专攻Student类操作的形式代码
代码范例:建立一个Servlet程序
package com.hbsi.servlet;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
/*
by:wzq
time:2017年11月12日
*/
@WebServlet(name = "studentServlet", urlPatterns = { "/studentServlet" })
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
Class<?> cls = null;
Object object = null;
try {
cls = Class.forName("com.hbsi.domain.Student");
object = cls.getDeclaredConstructor().newInstance();//获取实例化对象
Enumeration<String> parameterNames = request.getParameterNames();//获得全部参数名称
//判断是否有下一个参数
while(parameterNames.hasMoreElements()) {
//获取下一个参数
String parameterName = parameterNames.nextElement();
//根据参数名得到参数值
String parameterValue = request.getParameter(parameterName);
// System.out.println(parameterName+" "+parameterValue);//这里会显示输出前页面中参数名以及输入的参数值
//参数名就是对应的实体类Student中的属性名,所以根据这个参数名得到其类型
Field field = cls.getDeclaredField(parameterName);
// System.out.println(field);
String simpleName = field.getType().getSimpleName();
//取得setter方法。
Method setterMethod = cls.getMethod("set"+toUpperCaseOne(parameterName), field.getType());
//根据类型来选择的进行转换并赋值
switch (simpleName.toLowerCase()) {
case "string":
//设置值
setterMethod.invoke(object, parameterValue);
break;
case "int":
case "integer":
//设置值
setterMethod.invoke(object, Integer.parseInt(parameterValue));
break;
case "date": break;
case "double": break;
case "char": break;
case "character": break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
request.setAttribute("student", object);
request.getRequestDispatcher("student_insert_do.jsp").forward(request, response);
}
//将字符串转换成大写开头的字母
public String toUpperCaseOne(String str) {
return str.substring(0,1).toUpperCase().concat(str.substring(1).toLowerCase());
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
this.doGet(request, response);
}
}

 页面代码范例:输出数据

<h1>Name:${student.name }</h1>
<h1>Age :${student.age }</h1>
<h1>Sex :${student.sex }</h1>
我们在表单页面输入“懒蛋,20,gg”,执行结果

 

但是如果将我们的所有的代码都放在Servlet类中进行处理的话,实在是过于麻烦,因为类的面向对象的设计原则是不同的组件完成不同功能。下面定义一个Bean操作的工具类
代码范例:定义一个工具类以实现属性的设置
package com.hbsi.BeanTools;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;
import javax.servlet.ServletRequest;
import com.hbsi.stringUtils.StringTools;
/*
by:wzq
time:2017年11月12日
*/
public class BeanTools {
/**
* 这个方法只限制在WEB项目中使用,
* 利用反射进行所有请求参数的设置,要求参数名称要与属性名称保持一致
* @param obj 要操作的实例化对象
* @param request HttpServletRequeat接口对象实例,目的是为了获得页面的输入参数
* @throws Exception
*/
public static void setValue(Object obj,ServletRequest request) throws Exception {
Enumeration<String> parameterNames = request.getParameterNames();//获得全部参数名称
//判断是否有下一个参数
while(parameterNames.hasMoreElements()) {
//获取下一个参数
String parameterName = parameterNames.nextElement();
//根据参数名得到参数值
String parameterValue = request.getParameter(parameterName);
// System.out.println(parameterName+" "+parameterValue);//这里会显示输出前页面中参数名以及输入的参数值
//参数名就是对应的实体类Student中的属性名,所以根据这个参数名得到其类型
Field field = obj.getClass().getDeclaredField(parameterName);
// System.out.println(field);
String simpleName = field.getType().getSimpleName();
//取得setter方法。
Method setterMethod = obj.getClass().getMethod("set"+StringTools.toUpperCaseOne(parameterName), field.getType());
//根据类型来选择的进行转换并赋值
switch (simpleName.toLowerCase()) {
case "string":
//设置值
setterMethod.invoke(obj, parameterValue);
break;
case "int":
case "integer":
//设置值
setterMethod.invoke(obj, Integer.parseInt(parameterValue));
break;
case "date": break;
case "double": break;
case "char": break;
case "character": break;
}
}
}
}

 

上述代码中使用的StringTools代码示例:
package com.hbsi.stringUtils;
/*
by:wzq
time:2017年11月12日 */
public class StringTools {
//将字符串转换成大写开头的字母
public static String toUpperCaseOne(String str) {
return str.substring(0,1).toUpperCase().concat(str.substring(1).toLowerCase());
}
}

 

现在Servlet中的代码就相当简单了,代码示例
package com.hbsi.servlet;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.hbsi.BeanTools.BeanTools; import javax.servlet.annotation.WebServlet;
/*
by:wzq
time:2017年11月12日
*/
@WebServlet(name = "studentServlet", urlPatterns = { "/studentServlet" })
public class StudentServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
try {
Class<?> cls = cls = Class.forName("com.hbsi.domain.Student");
Object object = cls.getDeclaredConstructor().newInstance();//获取实例化对象
BeanTools.setValue(object, request);
request.setAttribute("student", object);
request.getRequestDispatcher("student_insert_do.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
this.doGet(request, response);
}
}

 

代码执行,表单输入“懒蛋,25,gr”

 

只要存在这样一个组件,那么在以后的开发里面就再也不用去编写接收数据,转型,设置属性等操作,但是整个操作的核心是一定要准备好实例化对象
除了针对于属性的操作可以通过反射简化代码之外,那么下面也可以运用反射进行解决Servlet重复的问题,几乎所有的Servlet都会存在以下的设计问题:
1. 需要接受的一个参数来区分操作类型,
2. 接收的状态参数(status)必须手工编写if else以区分执行那个方法
3. 到处充满了重复设置,sg,path属性的操作以及跳转代码。
 
解决操作状态的问题
1. 操作状态如果不接收,那么是无法进行操作的区分的,但是每次接受操作状态的时候都会感觉 到无奈。
状态例如:localhost:8080/tes/studentServlet/update 此时就要求的是更新操作
2. 在HttpServletRequest接口中定义了一个取得请求路径的方法: request.getRequestURI()
代码示例:取得状态码
package com.hbsi.servlet;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.hbsi.BeanTools.BeanTools; import javax.servlet.annotation.WebServlet;
/*
by:wzq
time:2017年11月12日
*/
@WebServlet(name = "employeeServlet", urlPatterns = { "/EmployeeServlet/*" })
public class EmployeeServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String requestURI = request.getRequestURI();
System.out.println(requestURI);//请求全路径
int lastIndexOf = requestURI.lastIndexOf("/");//取得最后一个/的位置
String substring = requestURI.substring(lastIndexOf+1);
System.out.println(substring);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
this.doGet(request, response);
}
}

 请求路径:http://localhost:8080/tes/EmployeeServlet/update

执行结果:update
 
对于所有的操作方法上都可以发现,操作的状态就是方法名称
 
代码示例:解决代码调用

package com.hbsi.servlet;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
/*
by:wzq
time:2017年11月13日
*/
@WebServlet(name = "dispatchaerServlet", urlPatterns = { "/DispatchaerServlet/*" })
public class DispatchaerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String requestURI = request.getRequestURI();
//取得最后一个/的位置
int lastIndexOf = requestURI.lastIndexOf("/");
//状态信息
String status = requestURI.substring(lastIndexOf+1);
System.out.println(status);//输出状态信息
//得到本类的所有方法
Method[] declaredMethods = this.getClass().getDeclaredMethods();
//循环判断状态信息与本类的方法名是否一致
for (int i = 0; i < declaredMethods.length; i++) {
if(declaredMethods[i].getName().equals(status)) {
//如果一直获得参数类型
Class<?>[] parameterTypes = declaredMethods[i].getParameterTypes();
try {
//根据参数类型得到其方法
Method method = this.getClass().getMethod(status, parameterTypes);
//调用方法
method.invoke(this, request,response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public void insert(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("执行插入方法");
}
public void delete(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("执行删除方法");
}
public void update(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
System.out.println("执行更新方法");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
this.doGet(request, response);
}
}

 请求路径:http://localhost:8080/tes/DispatchaerServlet/insert

执行结果:insert 执行插入方法
在上述代码中method.invoke(this, request,response);需要区分参数是比较麻烦的,而且必须是需要匹配好后才可以调用
以上的代码调用严格来讲算是一种习惯,因为各个方法里面需要有request,response等对象但是也同时感觉到,麻烦程度很高,比如需要知道参数的个数。
如果不想做参数的判断,如果说现在像insert(),update()等操作,那些地方可能使用到request或者response,接收参数,跳转,
代码优化:

package com.hbsi.servlet;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.annotation.WebServlet;
/*
by:wzq
time:2017年11月13日
*/
@WebServlet(name = "dispatchaerServlet", urlPatterns = { "/DispatchaerServlet/*" })
public class DispatchaerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
String uri = "/errors.jsp";
String requestURI = request.getRequestURI();
//取得最后一个/的位置
int lastIndexOf = requestURI.lastIndexOf("/");
//状态信息
String status = requestURI.substring(lastIndexOf+1);
try {
Method method = this.getClass().getMethod(status);
uri = method.invoke(this).toString();
} catch (Exception e) {
e.printStackTrace();
}
request.getRequestDispatcher(uri).forward(request, response);
}
public String insert(){
System.out.println("执行插入方法");
return "/insert.jsp";
}
public String delete() {
System.out.println("执行删除方法");
return "/delete.jsp";
}
public String update() {
System.out.println("执行更新方法");
return "/update.jsp";
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
this.doGet(request, response);
}
}

 执行结果:执行插入方法

此时Servlet已经可以反射调用,而且也可以反射将表单的参数设置给属性。
 
总结:关于反射设置数据内容的情况
代码示例:定义三个类,Emp,Dept,Company,三个类相关联
Emp> Dept > Company
代码实现功能:可以深层的为对象的属性赋值,
EMP属性:

 

private Integer empid;
private String empname;
private Dept dept = new Dept();

 Dept属性:

private Integer deptid;
private String deptname;
private Company company = new Company();
Company属性:
private Integer companyid;
private String companyname;

 工具类StringFirstUPTools:

//作用就是将制定字符串的首字母大写处理
public static String stringFirstUP(String str) {
return str.substring(0, 1).toUpperCase()+str.substring(1,str.length());
}

 核心代码实现:注意不适用于自身赋值

package com.hbsi.servlet;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.hbsi.domain.Emp;
/*
by:wzq
time:2017年11月18日
*/
public class Servlet {
//emp属性操作需要当前类对象完成
//emp.dept属性需要由emp类对象完成
private String requestParamName = "emp.dept.deptid";//模拟多级赋值的操作的参数
private String value = "6666";
private Emp emp = new Emp();//必须有实例化对象
public Emp getEmp() {
return emp;
}
public void handleParam(String paramName,String value) throws Exception {
String[] split = paramName.split("\\.");
Object currentObj = this;
for (int i = 0; i < split.length; i++) {
//根据拆分后的字符串得到相应的getter方法
Method method = currentObj.getClass().getMethod("get"+StringFirstUPTools.stringFirstUP(split[i]));
if(i<split.length-1) {//判断是否为最后一个对象而非属性
currentObj = method.invoke(currentObj);//将得到的下一个对象赋值到currentObj
}
}
//根据属性名称得到属性对象
Field declaredField = currentObj.getClass().getDeclaredField(split[split.length-1]);
Class<?> type = declaredField.getType();//属性类型
String typeName = type.getSimpleName();//属性类型简单名称
//根据属性名及类型得到对应的setter方法
Method declaredMethod = currentObj.getClass().getDeclaredMethod("set"+StringFirstUPTools.stringFirstUP(split[split.length-1]), type);
//根据类型来选择的进行转换并赋值
switch (typeName.toLowerCase()) {
case "string": declaredMethod.invoke(currentObj, String.valueOf(value)); break;
case "int":
case "integer": declaredMethod.invoke(currentObj, Integer.parseInt(value)); break;
case "double": declaredMethod.invoke(currentObj, Double.valueOf(value)); break;
}
}
public void get() {//模拟请求
try {
this.handleParam(this.requestParamName,this.value);
} catch (Exception e) {
e.printStackTrace();
}
//验证
Integer companyid = this.getEmp().getDept().getDeptid();
System.out.println(companyid);
}
public static void main(String[] args) {
new Servlet().get();
}
}
执行结果 : 6666
使用此类操作可以无限制进行数据的赋值,排除自关联的情况
 ClassLoader类
当使用java命令解释程序的时候,会自动根据CLASSPATH加载所需要的类文件,而用户现在要也可以编写自己的类加载器。
在Class类里面默认定义有专门的取得一个类的类加载器的方法
取得类加载器:public ClassLoader getClassLoader​() 返回类的类加载器。
public class ClassLoderDemo {
public static void main(String[] args) {
ClassLoderDemo classLoderDemo = new ClassLoderDemo();
System.out.println(classLoderDemo.getClass().getClassLoader());
System.out.println(classLoderDemo.getClass().getClassLoader().getParent());
System.out.println(classLoderDemo.getClass().getClassLoader().getParent().getParent());
}
}

 

执行结果

jdk.internal.loader.ClassLoaders$AppClassLoader@7960847b //系统类加载器
jdk.internal.loader.ClassLoaders$PlatformClassLoader@2f333739 //系统类加载器的父类加载器
null

 

自己也可以自定义一个类加载器,只需要继承 ClassLoader即可,此类定义如下
public abstract class ClassLoader extends Object 类加载器是负责加载类的对象。
ClassLoader的子类只需要重写loadClass方法就可以进行类加载的实现
代码示例:做一个默认的类加载器
public class MyClassLoader extends ClassLoader{
@Override
public Class<?> loadClass(String arg0) throws ClassNotFoundException {
return super.loadClass(arg0);//直接调用父类的loadClass()方法
}
public static void main(String[] args) throws Exception {
MyClassLoader myClassLoader = new MyClassLoader();
Class<?> loadClass = myClassLoader.loadClass("java.util.Date");//与Class.forName()作用几乎一样
Object newInstance = loadClass.getDeclaredConstructor().newInstance();
System.out.println(newInstance);//Sun Nov 19 11:51:29 CST 2017
}
}
上述程序只是继承并直接是调用了父类中的方法,与使用Class.forName()作用几乎一样,因为都是默认实现,下面使用自定义的类加载器加载指定文件
代码示例:创建一个Student类,并且把Student编译后的class文件复制到D盘根目录下,
package com.hbsi.domain;
public class Student {
public Student() {
System.out.println("student 实例化");
}
@Override
public String toString() {
return "Student 学生信息 toString()";
}
}
实现自定义类加载器,---加载文件数据
package com.hbsi.servlet;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
public class ClassLoderDemo extends ClassLoader{
public static void main(String[] args) {
try {
ClassLoderDemo classLoderDemo = new ClassLoderDemo();
classLoderDemo.loadClassFile("com.hbsi.domain.Student");//参数必须是包点类名
} catch (Exception e) {
e.printStackTrace();
}
}
public void loadClassFile(String className) {
try {
byte[] loadFile = this.loadFile(className);
//defineClass() 将字节数组转换为类别 Class的实例
Class<?> defineClass = super.defineClass(className, loadFile, 0, loadFile.length);
Object newInstance = defineClass.getDeclaredConstructor().newInstance();//实例化
System.out.println(newInstance);//输出调用toString
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] loadFile(String className) throws Exception{
String[] split = className.split("\\.");//拆分
String name = split[split.length-1];//取的Class类名
File file = new File("D:/"+name+".class");//拼接路径
//内存输出流
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
//字节流
InputStream inputStream = new FileInputStream(file);
byte date[] = new byte[1024];//缓冲区
int len = 0;
while((len = inputStream.read(date))!=-1) {
arrayOutputStream.write(date, 0, len);
}
//将内存中的数据取出
byte[] byteArray = arrayOutputStream.toByteArray();
arrayOutputStream.close();
inputStream.close();
return byteArray;
}
}

执行结果: student 实例化

Student 学生信息 toString()
在编写自定义类加载器的时候有如下要求
1. 不要重写loadClass方法,因为此方法会使会使用部分默认系统类加载器
2. 如果是手工加载方式,则可以使用方法进行转换:
1. protected final Class<?> defineClass​(String name, byte[] b,int off,int len) throws ClassFormatError 将字节数组转换为类别Class的实例。
此时的类加载的方式可能发生变化,那么就可以将程序继续扩大,直接利用HTTP协议加载,我们将Student.class文件拷贝到WEB目录下,这样就成为了WEB资源,如果要访问,必须基于HTTP协议完成。如果进行网络加载,就必须使用URL类,在java.net包中,如下代码,
package com.hbsi.BeanTools;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class ClassLoderDemo extends ClassLoader{
public static void main(String[] args) {
try {
ClassLoderDemo classLoderDemo = new ClassLoderDemo();
classLoderDemo.loadClassFile("com.hbsi.domain.Student");//参数必须是包点类名
} catch (Exception e) {
e.printStackTrace();
}
}
public void loadClassFile(String className) {
try {
byte[] loadFile = this.loadFile(className);
//defineClass() 将字节数组转换为类别 Class的实例
Class<?> defineClass = super.defineClass(className, loadFile, 0, loadFile.length);
Object newInstance = defineClass.getDeclaredConstructor().newInstance();//实例化
System.out.println(newInstance);//输出调用toString
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] loadFile(String className) throws Exception{
String[] split = className.split("\\.");//拆分
String name = split[split.length-1];//取的Class类名
URL url = new URL("http://localhost:8080/tes/"+name+".class");
URLConnection openConnection = url.openConnection();
//内存输出流
ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
//字节流
InputStream inputStream = openConnection.getInputStream();
byte date[] = new byte[1024];//缓冲区
int len = 0;
while((len = inputStream.read(date))!=-1) {
arrayOutputStream.write(date, 0, len);
}
//将内存中的数据取出
byte[] byteArray = arrayOutputStream.toByteArray();
arrayOutputStream.close();
inputStream.close();
return byteArray;
}
}
以及Student.class的存放目录
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMwAAAB+CAIAAADnQmnbAAAgAElEQVR4Ae2dCXwURfb4uyeTQICQyC2oCCRBEXHRvywb1gtESBCNwOLx8wd4bFABE10RD/z5180qivxNFFCiIOq6i6gYFRKUXQ/4ExUUPCCuZILcV7gScpBjZn7f6pqjM1cmmckQwtSn06l+/eq9quo3r169etWtHj30W21tbZ09Wa3Wtm3btmvXrrqyKioqqry8nLsnTpzo1auXxWLp1KlTaWkpCBIIBByS0WiEgMFgAEKRiooKSYRLVVUjIyNBqKmpqaqqIg9xRVGqaqojIiKAQwp8MjExMdw9efIkcBIZ+DrgqhoBZaiBXFFxIiYmFjpwVBSLg0hZWRl8u3XrZjabraoCnCJHDx+hVIcOHdq3b9+mTRvYAa+pOnns2DGqB1Po0GqLauBMDWtqTsILypDirtlMiXD/BNQ/Rp4rXclTr6yspDeRGCA8pCghAEYeAE8iOjo6NjaWuzwGnpN8AMgBt0CIatPGYjYjZBDhccoinA1RUVZNQMGELLfAh6YhIqK2pkapMsCIBymJcBfKnGEBPhw7duyIWHAXHDDLysq5RFYQsdLSNtSZfESEobKyQlIAQsVgREGkDUZt20VzGWWMpGIQhA5AZBdGluh2cKGZ0ARO5mRtHXWurq6mLHQgDlPqQ03D/RNg/xiPHz9+1lln0aE8KvmQyKAAzDVC4OhfngEZ2CCFPCESj4dnwwNDsOSvX2oviPAsgUtZUSoqUAwkKTQOFhSBSGn5CR42dGDKoxW6raoK1mgvIMC5CyZwICBQRNOw7aBPfcCBe02NhfpDmUtEpEuXLlAADrLBKCSb1KFjjJBrTaRggYxCk58QVSUjuUC/1iyazyUJgig+s9kCcllZuH+sAfaP8dChQwwcSBIPiSeBuPCEeE5SyHhmAOlr5AY545IHT+J5yMcGJkApSTxRSYSRkQQcUlL/kac4eZ6rJAUCRAByJgFEekADh8qARsO45JFLfKtVLS8vg6mjJohXaekx6CCR1BChQThEd9TWCr5Ct9ahxuos5ghtKASHegJE1UVHtZGsYQoyNkBk22gp3xCB+8GDh/hRUWUUW7h/AuwfdVvhRh7keX0vpmcbTFv3WyIMyrlnqdGRaoPIZxRCVa119zGr2aJcdDZm4pmedv+2RbUI4x4ri1+1EVuenJ+9cuCE9cp+EQZV0cYxPwudEWhtjWq/LuraYvNFZ58R7fXdyLi4uNqT1YwwkVFRjC1i0nfkyJHuvTr7Libv8ktFk1mEpRROrj1Az9A/4UQPCIurugbDBhPlwIEDBkzgRvXNKdVhppf+qN67uoU+x1PaMy2rTxgrMW2xejkzVIr5FNa6/3VEi6HJOCqP7Nn86uRv593IQYZLCW/wnHePGnlPvgOtKHtY5B+zizSaAF0uHWgyI3SoxVYBl1sWa/69EWqkPHT03dC8FQ8UHtbvDinq0q2bdExyZug0MHtCpzlu+5WhO63KD0unX3zzE3+YsZij/9j0rcsfB+jPMfqGNGXLtmIbsinvvQLl6+V5RbayRYUFQyeM6eeNlKyf+938qW2MKcon1upa7bgh96pskz+V0eGYXr5CnZbvVxM8l/Kr784IpONHjzL3JzFhZ+g0MjtlGt/Dre1ffvnlt99+O2vWLJc7PF8Mj/+8fUdE7f6qg3nWrtdVHdhcuW9zXEflx1fH2pHVDucO7jPmKftl/f/xA4Z+vXyVKX16PPCiX75Ou+vunF9MikVcmrZtTRr/l3hvto2ULre7+dPH5tz1ifXl0aJuIo1e9IUjLyF+nL0Qb6Cko1R4vu3oqZKSEiaVXOKEEg4qqdYct2Xm888/nz59+pIlS1zgXGJ5cJTu2dr/xmkR7c4xn9xh7NAupt//6TFkdP/r77Yfdx36KV9iejj3GzPuDwW/FGmk8nMX352acWHS4o80/KJVH3w9MKGf5JI/LVL4SjiueclkoyMq4ISjeAQcIn/IyhglS7mcncjRkVM/1SqvURj28ktTdcRBS5j5tbJ4rBp9ZbZJoDkL2rkDaaCUe3edmZCuXbvispAJATMwZDLV1PcFEnb//fdffLFnz5l82LV1lpiuXdu0i45sY23TPqptx5h2Z8W1YYXJfoDgQbxszzh+9PikJR8Lqfr045w7xyb3TZ44dMs28WiLCr+5O3Wk9oynR2VeUGitqOYoGvdewnRNnhinltyQO1YArRUfpS25wSY3wD2xy58elVL4QpFGBHwlNcqOrxQ8/EuqgBdmKX+ZPN+U/HJ10fNDlTs/slZ8md7XSkFP3Bsope/FMzqPUOHxRrxwleE/F052ZgGOLnFIGPNPB9AlwwBRx2S91mbJ4Vr/5Zv1v/24yaKbwdeerFv55NWioFUd8/QXLhT6pkwc8v62YiVh25ak/g8q1n5jblIm5xenJ3ySM+SCmdBXVucuUQqUAerD9pJDikzW0cIWuvOjRSM1w0kZPfO5oQmfrBaXMomC+gSRoVk/zYi3wR34o0FKeu7BZAGH9dDlZOQBQAC9cG+gFAXDSesBaeUzYrLEImwyfGWOnvFTwtAZKCqlTghZye7dG1d/Nuja0cMnpbFiJEjZpFMlc2jnjm9XvAO+a+qbeNE3uSaT8oEy8bW+KKH4hIsKPikyKVuSxj8Qb8MfmvUjSkVX0mo1cSWkQUdQXI5KvePGzHxT+n39dNj2LMg69KT+8ZrO0wg56WiKsB5xD9yZAQv23krpuNh5B/yfFTy0AGt9nAMmFhwCaB8Zi+BDDbGyh9cCflKFicVsuVYIaOPGjdzetGmTrM6UKVNkRn+mi3EK1GlCVrJn37qP8q4YN77reedqOEKwNFETmZLdu75ftWLIlCzw3VLymLtSPv5/acr4medDUFFGjE0b9/HcKcpExErgX5c65caUF1enZ48SRddMn6rMFxoLzDc+zs+6Lhng9vmTZ32T9v514CffPzdz8EXDLFvW2+Ts06kji2aumS6I/PnlMWu0KYby6dxZysTNGn04SNcGdMTTkw4UTXx9cPddyil8EAxSQsiYoOFjYl04SCQDJYP3HqFHznwIGcMlOozV5Oh27TiJ5WHUWkwXwZu5pPt00qVSdDRHrdlasmP7upX/vuLG5K49YpWaUiFbegnbs/erFSsH3zqn5yXXge+erh2bNiE1Z0ruItvdUalTUlOW3pWXpdFXlOSsLVnXDVTlgteUXKsdrkxRcmOjUzSCae9VLbpWw+8zff3xhKlxA9VHJae78o7PZ5SMz6rKy4hOiJ0poeCn97HRFxB9xUAeNT7p0VR16dCsTV+ke+Puo9RPa9MlmyCesWSQs5YjYTSNyjAayvACby09evQoXgumlVhm1F8t3Lwezdb3wsu8FdDDP/uP+Y99I2rMyqqHLiLs6+qxV3ft1c2huhyZQ3sPFnxaMHDcU70uuU5fvHXnoyKU/7/dfN0FEUFsJmqDJ0osVhBpBk6KsBQmiz5Ef+e2H6g2QoZKE4Y/qhhx858xv36ODucOOvbb5nV5a1WDURGBOiya25JqiOjW/4qrHvqkTUwXvaqw32+1/8+oxvp+igT2SaHijFkmYvekjea7mOOuEDKrMuzepSdPHHYA9Zm2MV0MkcLoaw4bRc+opeXDQuZ4Ilj5qDE5WRFRGBhkwrT0Tx8zItSZhemFGLXr1MtBNJxBk9Mz9E840QMsKGG0IVoEfjJuiuES08zPrukeo+4rtZxzlti/EU76HmCKuueYpVuMw2rQ3zzj8gRfyBhm7DakzYhmY+3Sz25I7Gb45aBl404Csf0scaagEUzGL/DC7uFfn3jimGJ4LZAzLDFh+BcXFyNk/Qd19Ucc6MqBZxsGhoM//emsMxhnz549DJQ40piEMjVu3HB5Bvdby236g48/v3PXvgbrd/55veb9zeYwbBA5QASbox/tZRRLSsbOnTvL/TkB0g0XP1U9gIR98Da+6gbS+P/OaAAjeLd79uyJLw25IhADIROb0vw3/INXjTCl1twDaDJcGAiZXIMSe/OZZLbmFp+pbftt5957Hnia41DJ0RD3ActK+C/QXywusYgpghbRaaGsRNXRPRsXTl4/90YOMlz6zd2UPQxrchiR1fVT/lQnWOJwLdNUAqq123aAEyxpaPgCy3NykNNQPFUA6rYaOXA1Hu7V9MyhuaAbvv+p5PBRji/WfdtcPLzQdcSTsY5OAKORWQBOfy/IjQAXFBRccsklLvGPHstvXDx9yJ0vRLWP4255ya4f//n40GlvesT0CExKUkTsdroI1pbJlJ2ZY8/L/2l51kUiUMOeFlmti8gjDrmp9e8oplXLlaSknNz8Rcn6EvaSSnz6+rxCNXNAkYNgWtrAjMnZY9brauDAVhRX1rpbzZpFby3/cPWG73/GwL9+1FXXXDlkyGWDvli7AabXXPH7BllnL3pXj5M+9Wb9ZWPz2PsMjygzXBgMmgYU2uHDnheIGkV6586dK1euZAun71I/LrVtDqg+cfh40ZqywmWxHZXv5o+1Hzds+/hJ3xQGTpyoZMzVaR4hJllZRLM1JYnCE9+cnYaU+V08dWaWgpi5qlO/yzcL4rsr8pEwSO/YtXf+a//Y8oupT+9er2Y9ydGta6cGWeqlSp9vsKBHBPZaEua/b98+RE28/AEbLVizy+HDh3/44Yd79+71yFgCj+/2sDkg8fq77cdd+39s6GknpiMTmY5nnD83Q5k4JtEHTx+3NBkbE5+cqqfoA1/eik9/EzFL8D7GNkgh+AgbN23RE30ua3FFZZUe0mBeylbgEgYjdBgWA2aYiPMhegKPf6OiMHzUldH3pptuev/994uK2ODmOfmzOcBzSR0UmSiwKTMxVKbNdh25clKk5aWqvgVBCigDr6DIIKzj4TsrxCwpJ8UDdQfrU2uSVVZW/eXxuQygX6zb8D/PzPfdGsfdoEgY1M7v2/fcc89FHvDExuCMRdYYMdvGBseLj9ft5ptvzsnJmTFjhscoKH82B7z36NVas9U/PfuFo/31Mskzs5ISMrNnJieixrKKMKbqqz8/DaP83JykiUWacYeUpWTaTD1MtxTNyEvKKvJieSnYam9mLU9ImZpqTa1XNT9Z1yvTPBeY/O+uODXb7RkjmVqSUGnCIYtpFkQXBnPXd99999Zbb/UoYXRmozYHeO/8eIbMjMxV2QMdUuId1+sdZIzNKgmq00k5Nz8d+z7ZNk/wWlDesIuZ0kRzsAHyp/NtPLGIFhKGnwyHmVhW8mdK6E+TmUDk5uZOmDCBd396w/d/c8BVf87yRkTAhepJyShAcTinmb7w3e8JGdPrHaHAvE4y3YsDkWKWkaMk+ayqx7LBBvrj9A82T6/0GCiRMMRLnsUOcoRMvHUu4PTvf/8bm4wR0wclPzcHDJs05/xLr/NBByljyMwpTPXod8Awsjs1vA55UsZ0xRFbxV3K8H1pY2fC1EQX54eonU3MfFa0uW/2Pq+nP0tGoDV3TRz02Y7EpFIGwzKtVLd8vw4hO7//YAdG0zJ++snemdbA5oCvPy0YcstTDUlY0+p4+pU6TWP8TVs34ugnmAwJQ7rE+1eD4oxNwknqR4rrPaik2LY5QHXZHBAR0evCK8bO/iS6o7Z3yg9qYZSW2QNSvDDL8F3gyFB5xTri1iHOqxUV3GaYa6uryjz7fpGtCG1zQHA5ntbUTlNNZq4+ymyS4bJN22irxSwmmEw1Q/YkEKMOnUMk0CFrVJiRSw9gkGHy4+fHOGPcrPeaAhfU8GW4B5rWA8gWCeVFMBkqTXwsAmXWNFrhUuEe8NgDBF+gxojuJ7GeJF5M7BEvDAz3QJN7AO2FXGH+44UVzlgWzJG72M7nNZliuGCz9gAPST6wZuXiP3Eqw8Kwb3zc8phiTC0RLURNGP5BcWH45hq+27Qe4HHykOQW2aZRCHophJ5Zo285Y4hEqEjiNYtoMr6phrgFvSphgkHpAWwaIhiQM0wcMkGhGQgRZAuh0WwtX5vlWfVhgokmI2H+C/8FK0td2/m17zKQ+oXLNqEHeKgMNZxbgoTJ+lMZhIyzj+YQu8rsEgQCJhAwAxchtv2bHOPPCrY+PkxE1OuCtuyX4r8u2UK+RFlH0pXS95SjpFZGXtVHhYoN4MDViNbH0tMMMA91NAceAJRZC0lUhipRMR9NQ7BAQPuCIzBPHNtTdeIAP5QA0/r163kBnz9Evnr+xqrDReaqEo7SXd9/PX+SP6UETl4a8Q5FNuyiLLGO5by23xRwgitckv2uAJP3gKEV0KFpdNL0HPUV8MzFhekZe1lZtr+idF9NZcnJ8oPVFYdEwD8GWuBRGMT47969+9prr/UdheGI8Xd8AEDG+Nt/FmrH8wYn3vCU/bL+/4QBSSJ+VW4i4asSaWlpOYVFxEKAZuIdxxNnkms4vBUySmF9yt6uCOffkuB914i3Ymc6HB8sHyFhVEXtYZYZCPhvcPeHn33W7DH+8WMmJhUIqSIRqZOWOnOA2GckLgnWLxiY6FdomUBN8xwiJCjVTyKWp6WF89evYUu8QqJ4exRyJj+fauD7SqdPjL+QMilVmowli2s+AEA/C73mFBxHoL3ehivISMA+UNUEIrZn6uLIGnhKQsxadDh/A/U/FbeJvOjevTuxq5zFC1fwXwRxWam5Y/yFVC1HqsQHAAbw9hCulckMoIlE64trW9IHvNphwnyzRexrMwhtaya51hDO72hjC8ngSMMZy5lppVi7FH/4Y4PkKWv2GP/4xIEFubzwX+yWFIOj/dpmkPnXySIGNhNRTY4Ph/P712ONxMIphnhhjeFGxmEmvnfJ1wkbScQzOosJK1asIMY/ISHBM4bYkSe+MlGyo2jdihWXjx51Tt9z27cziKN9RPt2HEbiKCuP7OUDAF5i/BGQnNy5hWy1lAaY67U3xnq4iLz204CzF5ODZk6O/Tr831cPtDFGxsV0RLT41ntshxjhg2EV01cJv+/JGH8fu0igZIvxz111xQ2jbR8AqClTassUzlqmZHvhV+8uGzbpWW8R2EKqcnKcMuJ6LarrtMnsfi2AdptMVVMUl9cYiDJMHrRwftA8bKeU4fx+Bf9KYmf0WUTDaj5bHBfYZCrh2CwwdT/vggB7JRzjH2AHtqbiu00/YYaJIB9tZdzIkIkyC7yF4Rj/wPuw1VDAc0FkLAl9Js57t29BoUXH9QxNC8Mx/qHp51PLpfTQDmRLBl6IKAx0WlA0mZ+tCsf4+9lRrQCNtUtEjWmmkT9yce3DURit4LG2lCbIVWxqQ+wFCctMvHOlpdQuXI9W0QMYYARi4LVAwtBiItQHz2yraFq4ES2lB1BbKDMkTMYpiRh/JO78jj1aSgXD9Tj9ewCPPy4M9BfmPq8paCD67PRvb7gFp6AHEC+sfhIuDDG7PPvss1ljCnFFVmVf6ZHjmPS1HuFh4OnVA4T2sEDOO7BtFv+h3b+eOLwrxDGcK7OuqK6pczm2fHwv8OatiS7yNQiMRHisMzQ3CAQbRcL/toS8nmUlO4/sM50s3V95bC8ZAxLHUnmIfyh1VnZGiK+u6o+o9p379B3oTcmFuIZhdoH0ADYZxQlaJCoH40x8ipwUCMUmlK0zG9jh5XIgZJHtO5/f96IP5l3jN02xocPjerbfFBpE9M6Cd/xbvb5UtkG6XhC8s/NSoGFws9TTF1uMfRITSpbFRdAidhnJV4lG3qu7776IJ55Qz/b1puNai4Hv3MY8n3myvLL8aFnFkbLOy97qPGi6ZPXzr6MayTOM3rJ6ANkizB9b3+YdK/zp61+3bmiUMeAb2bxyZe3QoXWvvWYpLfWG+dacEccrao+Xez64662gsC5siehXse3IljCN9BuI9Hk9GthOI8pZ3A7TzBz7dyc0oBNHV9BeOycX94ICp35tZSknQTtTSUWD66MM7LftzFyLi4Y7cZxkPezEctbTvUo67lpXum/0ql8Bv662FW5EqH7atG7Pjq0l+03ChRGseDKtkophzJiIN9+0LFtWN368ZdUqCXQ515r5Op119fqt/8z/7oW3v/jLix+ZLdY7nlrGmYO7Lvi2S1P25IyB9t1u8jXV9v7zOmqJAGvCx9weEXC+ZSPBRROXO2LICjIKUwW0SH51hNDZBlnI2rkUFOFp9WsLmjemBMDxPR6rlX2Fvtj5aEvKFsdewTwlxZsF4aFKovI27lQgL83jxwlkC/0/s0UUYkSVMWiKzb3keFOB/+X9wVQTE40rVihnn23JzGT0tGza5FKqxqwiTMN/f+H4kZfef+tVz84Yy+WixydKIeOuC77tklhrEY/YmK20BMEmObeNEOBoIyWCYx1RjAkZBYrcjyKUg9xkInYTeK6FF6hbQffaemXKNlDHp5u8kAfsoy1JWW86PpihvbHZ81d83KukcXNy91HWe73c7+DCQK54BzZnBM6AJwOnmTtegBCV4I633lJSUpTNmy3TptX99a/W/fsdNGvMBsKwu774TMzTs/mc+aK3Vt/z5FtDb3+BPAd3HZj1MyIk32p9U5mM/m2MqNWnYrtyjjWCqFdV6LGsX0BPtW12prJmSQM8B8B7qpJfbWkcEv2JUOG4YG8c7/QXa5dskWscDb+xjU88YZg929q+vZKXVzdpkvn112VRDH8Ee++Mx448lolU3XHb6JeemLR26UNSyOosXoTMlJ0tNlkyWWIIs2/ArFcZmz4SWyslHN1l/0KOGMAcn5OrB2cYa4YZqnttA2Rar7hrW5wfFHN8y0fMU+v/FN2rpPWS4+tlYjjVby2s17eNuCASFiFj7RL/BY4M8b1LArEbQaCRqJhoxoULrT16qLzEYPHi2ptusqxdK2wyi/WHfX9fY8p5fdPcRz5/bMIH9w554zb7cOlFyOLZ+oYOIyVgm2kDjBjVREQ/nWnbhytuTy4caB/rkhcJO0MAASsT7cMlnx0pytpi/wRTbqqP0UrHolFt91Bbf5j6YOe9Lda8gbZdpdoOBm9q2UOVRJPSFF23evhaQaOaLZCx8hkoGTTZd8lZPX54p5hqtg+yWeZSL2tZmfmRRxg6JXxnrDFq7t/runlelX/nxT/NnvOxC4XwZdN7AJWWUDjbs/T4utdkjuXH9+LC4DUFcgOmYdeuXUH53qXvCmGioc/Um2+WaL1L685Ou6Xj4vnWslIXlyyXdd4Mf988mv0uk7t6qRmGWH0bgsZOGA/ejDQ9w+DlCe1BqHbs2HHo0CFml+JjEcEj3gCliIwMS0KC+cUXVe2r57GfvB+V98HqPjE/9hDjNUtM4n1EVv68zC4bIN/ct4XVLD4AHKIUDHbC6ZGjec4ck89Q1J7hEqsfrwWDJPaYundnIYEYamRcKJhrPKzbttXNmqUeOODgaE1MjEhPN1x6qQMSzpzWPVB6ZNfJkyd5ZwUjJhl1929bkLtO3fqEslUuJpqN9ZVXoup8r0eFspJhXk3ugUP7ijAsGCTZPkKKeOjB6XgxOsaFdCOJ2qYNs05CdJWtW50t2blTrBDwcuX4eBCc8HDudOuByvJjyBY6DBcGjgyVNy3i+w/lcKnvMdwZ5qefliaaA46/I+KBBwxXeg5sdKCFMy22B3jHIpqLEZI5JoFk6oE9v+In69jp3FNVY2GiZWaq7p8tHzxYjJ6JiaeqYmG+Te4BbDLKMlwytcT7HzH5v29hY0nX7uc0mWKABdXOnQ0jRlh37lR2iZo504ED1txca0WFOmBAePR0dsvpkNu7u5hlJLmdhPqy6RIfVqiDFj2Ev/ZS+g00xG9xXUW1Es2xcqXh7rsj7D6206GTz/Q6Sncivn5cGCJ/5OB2PBlRoX2PP0I28r4vXB5F0eoZFWt/Gry5rYuJJtGEocZKaIBuDvxGBPh4W3VxqVCDl8Jbvnxi0Mh55xcyRt6r0Kg7vE+99mQ1ciXjYVmotjBwNopE4MjeYvw7XDno6z+etHp6hx5+NRHNMWuWPpoj8JqEKTRHDzCpZGqJGcagyZuvxUYSQM3ByQdNHzH+nS+7OO+CncoVV3guzmx03DiiOfC0aQj8xr1F6Hkm0HiodxbNEjvviV2zMGp8T/hdArWF8nJ4MYzMM0P/moIGY/yNzz8vJGnxYo/tAl63alXE3XcbxvT3iBAGntoeYKAkMFA6Y8WgGfqxkvbXWlQs/NKZs6ufeiby5flx/3hLRpLJc622QC5kaMECEYvmKYnRMzNz64Ab3vihnS3UR68C9HkR9GxP8lXXNoJOuD3qCsiw7GwbugYEIuJmbSxcauLk4l5QoIr7tuRYTHdnKqlo8GHDhnlk52TkTlNXXOPl4ORS2VBeMjYyVjJIos94U4Fh3759IYjCcGmhnzH+mPnGt9/2aKJJgv1jY78bNOirtKct+XfoPxRh+X7PsLPE1j8trL7VxPh73DcgGhn0IH1BNIDEdkv5ERIiFnHGGlnCDGUghqy5I8bf0RBHjD8QfYw/S5nG+fPN2dnE1jqQXTJJP+XVjV9rGNlbUcT38cTCaM6303orv2K3rRcx/kX2T0MQW6ps0Upr4fZKgpphp5UkXrnOhT5Uf7n9pj//3QqKgPqMFJUdHvbZrFem/sX4Uwt3mlrV6gfpJ+TmL0q2N9mfqgcdh4jF6soq+UVVocmIx/D9NaSg1wCCjYrxF7FobORMT/dRExF2++HWf/7ul7hNm8zPPKNW1vZqW9vvjTd8FNHtJzuNYvxDFKTvq9/8uIeHjD29pJjY2LZ8IZqNJCxh+lEwmChNiPGPuOUWw2PDq9t4NtFk5Xq2rb182jTlq6/kZe9ly6z9fn8ax/gLc8tuLsomhSpIP8CHLUdJvBiHiVo8cEDsIMdAizkrQLKNKy5j/H8+8E5JZeXOslLT8WOmY8d2lZV+PfkdCHnbrWQY+7cNK9p2+D5xsJfZgHsl6v72FTH+aopK5J4YCtm4axsDRbj9MD62pJURn8lxL2yDiKB7hj0x7NrHPa+4+hsE1M8VEfciwUCMX/4w1bF7UyurP3mgKW5rQfoOTj72K+hpNWMezWWuqUXIMMhYKcmFDGkAAAnpSURBVBdRGPj+jW07NyNPN9KZj9xw+4PvEQrrMfmO8Rcml08TzYWmmpFx2i9JodJCG6Tv0oeNveRjl7gw5HujmGAa8MkSj9FYKgHi48LA0neP7pcQ3zH+/pho+upZ8Lft26eHNDXv9D5Iv0TInAWhD9JvahfZyuG/YHWcjXF0lFBhDJpsv7x4cM8A6TaquNlieGPerSKsX8T1M2QJndaoGH9MNOull7I93eNCp74yzAnML71knDNHD2xSPhhB941ljGCfiiD9xlbTBR8XBsMlXgvUGO4LlXdj4PE/r+/FLninxSVDZ9306R5i0dxqb3juuXAUpFuvNBeAmH6+CocOw5fB4pL4qGrPniFVY0FsGUOn7WUIDRE1Z2XZlzsbQg3fD7gHeJEny5X4ySK1uEUD/otgfR464Lo1kYA/8T/q/v0W326zJjIPF/PQA8wrZeD10SNH2Nhr5KOEKDQPiMEG4TvBGIR9cAl3WLeu62uv+UOT+MedF11U05uFgZaY5OAS+gDS5ugLxkoc/SyLY4mJ1xTItxLHdDmvOZg5aGIJ4jKBX1RUMLchWfPy1GefcXBpMMMGT3XxkgbRTglCTU01vSS2J3bqdEoqEEymtaW4yJjW8ctBpYmvxOGP7dH7wmDycKP12/btvXqdI3eIu91sOkCYWSaTWlysMFv+4Qfl4EH9nmGPdC0zZigTJni8daqBKhPsvXv39Onb91TXJFD+xw/+xpCFkLERjgmmkSEMp5nnN58EystZvo7X7UXwJh9bCP8PxQfvX7ia22vnTXYiNSHH7oRLL8WXQVGnZ5d37pWXqyYT8qfs32/Yvl1PWH3jDUtSktIS5zrWiAhepRvqKGV95wQrTwiGtMGEJ5aPRRBThicjWNR908H9KhEijUaZWfdGqqOIMbLtpakLotoFPFj8bjA0rX+0xdYKueaVCPv321Rd4do3b3l02JdL+zkYBy3z6fToj8dWLRjVZIJeXpnVZHqnqiDvWMQ6gjsmJvrMyGwTcQtBbWDGe/tdGF0+wblm+MvqmQXLplyW+lKHTr1d0HSXPMjUJdr1nblV8/18nj26Kz26Wwf/TpT7dPfUORf8LFy/QU+SZtMpix5qFUl+iwS5wibDfRG6jSR0oGMhaf/RE7Iz28T0dBxdevaP7dj52/fuKT+yw4FZPyMkTPmwsqKC4+cL5kz7VKxDmeZfEz19tdtnAbwtWokH6TeyjYifLGhTYynXx28lMqbIXSOMmHIHiTGEC5f8UG0qs7xKBBdFt4kk3tqRIqKiu/aKr62t/jZ35jVTljngzsz2X7cMee71kTx5YH3u+9dLQmzFc+XhSqAT12uOsqKQfeT2iqe/4ScL0RghNfqijcsHULRxjJoXm8gLuXEEZYYjQ7xivVlf5+loDZJhsVifWVbw3PJvsj/8BnjKkES9uuly6UPdh/7PBcnZNWaB6eE4P+GiDbNeXK2/9dmMDoNmbVCWjOvQYfiCoqIFwzvMWC3L6vMW0Oxp3BJYi+V5cTjhw+cX2yHD58+3oWvA+izqVcylONaAvW6Cuy3NsFe4aL4OptFxgWg/HkeHncYZhktqj1zFxsXhkTEy1UStxXRp9iaJn7jVsm3v0V0lZbHGqhuGJ902fJC7NYhu4wt2mupwr9KIrPenxE6IeUOZ8n5p9khxf0RW6ebEkYN/fVi73r4QVWLXUkK/afk16bETlPdLS7UC4qLQYoc/339zaanwGGxfOPKS++Mhgh7a8Mh/Hi4tzRKwwX9eMGpNPRZORaVRenZz6X02jwPv/oefRnn7wmzLIklYYM0YA+HtC6c+MuD90jVaLTTV6w6xa3r3lp9eEBx+eC2YV0rD3yB3lYSmDYyXr6eP/ixz4p3n/eu/RlyCEtVrsv0Hj9bU8eZ1ax1Pylu6NovYpE3PFk5g6TX9M4klKm/D12W1kUeAP1u5dMiz919rw7h2zBQbOnBlw6ODIUQa/OgGpbCoGCRFsWP3GXXTEBtlPV0bIY3sq/f2sV1q/2yUrX3uzbrXunCkIDxhqQ3YJ36AsnRC7MiFgomW3CCCS6tIBPlgjZEwxsRwiYuZWOwQNI3BiC2ftkPEkylrv/k55fbHPy/4kfycBe+mTJq9/+Bx8oV7IkdNevrzgp+d+I6CWqZ32uojR5ZPXvqn9E8hKHQLo5RAFoaZlX/18uK2Hajh2C6BX/7Md0dYXrMd+Wnni5fQCGKynpruFXkdC0lcT8cBkWW5NC0cGRc31fKKoPzdM5fbqjRinmD0imUqg8nIBSbIukLoohA8iBCw6NKlC6/v5NXX+DJorYGBMzSbe+VwKc917Lu0Kk/Oe+vWcSOefvHv5A8fLUO7kuFYviH69puueuql5foiIl+8cPQDaC+7+lMuT+hD3syTsQHF6Is+EgjFqz/cKPSbxToiedLGx15aI0uZXnmBoGZhfdWHW9Y8kLFGUhZDmUTWKIu8jgV16DzqFVjUI/vZK6+YBC/J0fSfjZdnLpjau141ihe+IurQe2r+hszLN/5qEs1xhbSW4RLPBUnugkOZGTDIUG4hkG5YyFGCs9mq8uzY/jlx7DUV5WwBtU6bchOxi2RQGydr1VuuTyovF+sS9VKfqfMT5/Er0dItyrK8qWKw6jPyxsvfuqVLl+RXi0HIVGYPEfenbbvwchvLEfOWTRIIGli5cZK9JiPmfZv5iw3eJS9lnvbZMK0n7FzFhcjrWEhdI4D64nnxoir2siOm2Wuhq0afqfF5sg5DZl+4TDBzg2jlW8MJkwahwizDOGNXr3rswHY67KwezbteVlRUhP6UXmB6MXfJPWPSlqXcNvOph+96Ys7rq5e9sO/Akdvueeofrz4ZG107dtJj856877Hn//mvvz/RGrrc7zZguuzfvz/B0/tm/KbRIhD5ci8mB44MlBmWmRG1xtplCKomfvy2HzseBKHJbp8wauZTC+/+r7HkSWIIE2frH+JrH/jr0ntuvc6BH4LqtQQWraa9TCrxWrBciSXG2VhcXIyQ9R8UihcTI0zyWZrNwiabeOOIcddfzR528p07x73zyv/lXF1Rcllfvvf1pIDb8VuCBITr4H8P7Nmzh1EL7wFRGEwrxVt9QvADQo7Rn0ZjhFycP3784NtzrvVW6ZjYbsYI1optEukNrZXB7V0UilGlubtOOvppEUnEk5Ue2kEQY3Rc84b5i6DFioqYjh21vUnN3cbTkj4/9RNlZe3at28FQYt1FSVsgUOucBQiZEZ8ZYhbcz8W2XG4iVpHvFRzdBfmgVyEaQ7iIaaJJsMhhZARgoG3nxcT84LpinbN745FzqSohbjBYXah7wEGLoYs9BeiJTQZq7ihr0SYY+vuAbz8KC+mligzZpoGZgEhMPxbd5+GW+fSAxhgDJSoMenF+F8oAiIpG9bVgQAAAABJRU5ErkJgggA=" alt="" />
执行结果:
student 实例化
Student 学生信息 toString()
在进行类加载的过程之中存在一种概念 -- 双亲加载:如果是系统类则会由系统的类加载器进行加载,例如如果现在加载的是java.lang.String,那么这个类会在程序运行时自动完成加载,而后如果用户再以同样的名称加载了自定义的java.lang.String,那么在系统之中就会做出一个检测, 如果检测出了一个问题,则无法加载,会出现错误提示。
 
 
 

最新文章

  1. Android之TabActivity的使用
  2. Ubuntu 16.04应用布署小记
  3. Android应用开发-网络编程(二)(重制版)
  4. ios -- 教你如何轻松学习Swift语法(一)
  5. 四、CCSprite
  6. (转)[C++语法] 关键字typedef用法
  7. svn文件清理Bat脚本
  8. 美国易安信公司 EMC
  9. 为iPhone6 设计自适应布局(一)
  10. 【Unity Shaders】ShadowGun系列之二——雾和体积光
  11. python学习之路之int()奇怪的报错
  12. cmd命令中截取日期字符
  13. 8 -- 深入使用Spring -- 3...1 Resource实现类ClassPathResource
  14. 【动态规划】POJ-3616
  15. RF - selenium - 常用关键字
  16. hdu 4557 暴力
  17. TotalCommander如何比较文件夹并提取出重复的文件
  18. cocos2d-x树结构执行动作
  19. Bootstrap – 1.认识
  20. shell脚本分析 nginx日志访问次数最多及最耗时的页面

热门文章

  1. [ kvm ] 学习笔记 8:Ovirt 基础及使用
  2. springboot maven 收发JSON
  3. python:如何传递一个列表参数
  4. 【转】JS中处理Number浮点数精度问题
  5. [转载]SQL Server提权系列
  6. 使用redis调用lua脚本的方式对接口进行限流
  7. [转帖]TPC-C解析系列04_TPC-C基准测试之数据库事务引擎的挑战
  8. [转帖]Hive 快速入门(全面)
  9. PHP 生成公钥私钥,加密解密,签名验签
  10. Spring Boot开启Druid数据库监控功能