java 分析类_java--分析简单java类与反射的联系
分析简单java类与反射的联系
web对反射的操作支持
在JSP之中有一种技术--javaBean。而且在jsp里面也配套有相应的操作方式,javaBean的核心在于简单java类,于是下面演示此操作
代码示例:创建一个简单的Student类
packagecom.hbsi.domain;public classStudent {publicStudent() {
System.out.println("构造方法执行了,对象实例化");
}privateString name;privateInteger age;privateString sex;publicString getName() {
System.out.println("getName被调用");returnname;
}public voidsetName(String name) {
System.out.println("setName被调用");this.name =name;
}publicInteger getAge() {
System.out.println("getAge被调用");returnage;
}public voidsetAge(Integer age) {
System.out.println("setAge被调用");this.age =age;
}publicString getSex() {
System.out.println("getSex被调用");returnsex;
}public voidsetSex(String sex) {
System.out.println("setSex被调用");this.sex =sex;
}
}
在web项目中所建立的每个java类最终都会保存在WEB-INF/classes目录下,所以classes就是一个CLASSPATH。但是要求是:
建立一个表单,输入完成后的数据需要设置到Student类中,同时再通过Student类对象取得输入内容
代码范例:定义一个输入表单
student_insert.jsp
纯菜鸟
姓名:
年龄:
性别:
此时Student类已经生成了对应的setter 和 getter方法,同时表单中的参数名与Student中的属性名一致,
代码范例:按照传统方式编写一个接受页面
Insert title here
Student stu= newStudent();
stu.setName(request.getParameter("name"));
stu.setAge(Integer.parseInt(request.getParameter("age")));
stu.setSex(request.getParameter("sex"));%>
Name:
Age :
Sex :
将此项目放到Tomcat中并且运行项目并输入,“懒蛋,18,男”执行结果如下
但是如果直接使用JSP的开发方式,以上的代码就可以简化了
代码范例编写简化后的JSP页面
Insert title here
Name:
Age :
Sex :
执行程序并输入“懒蛋,19,jj” 运行结果如下
下面来看一下使用到的三个标签
1. 定义javaBean对象:
1. id:表示定义的实例化名字,Student stu = new Student();
2. class:对象的类型。此处是依靠反射实例化对象;(调用无参构造)
3. scope:此对象的保存范围:page,request,session,application
2.设置属性内容:
1. name:表示的要操作的对象名称,与id相同
2. property:要操作的属性名称,如果为* 表示自动操作,也可以指定,例如
表示只操作name的赋值,参数名称一定要与属性名称一致(setter)
3.取得属性内容:
1. name:表示的要操作的对象名称,与id相同
2. property:取得输出的属性内容(getter)
但是此时的控制柜台就输出了
构造方法执行了,对象实例化
setName被调用
setAge被调用
setSex被调用
getName被调用
getAge被调用
getSex被调用
在Servlet之中自定义反射接收
对于WEB而言,发现“”等标签只能在JSP页面使用,但是如果是一个真正开发,一定是使用Servlet进行的,所以现在就希望编写一个与之类似的功能,可以帮助我们实现此类操作。
本程序继续使用之前的Student类与student_insert.jsp页面,先完成一个专攻Student类操作的形式代码
代码范例:建立一个Servlet程序
packagecom.hbsi.servlet;importjava.io.IOException;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Enumeration;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.annotation.WebServlet;/*by:wzq
time:2017年11月12日*/@WebServlet(name= "studentServlet", urlPatterns = { "/studentServlet"})public class StudentServlet extendsHttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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 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);
}//将字符串转换成大写开头的字母
publicString toUpperCaseOne(String str) {return str.substring(0,1).toUpperCase().concat(str.substring(1).toLowerCase());
}protected void doPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");this.doGet(request, response);
}
}
页面代码范例:输出数据
Name:${student.name }
Age :${student.age }
Sex :${student.sex }
我们在表单页面输入“懒蛋,20,gg”,执行结果
但是如果将我们的所有的代码都放在Servlet类中进行处理的话,实在是过于麻烦,因为类的面向对象的设计原则是不同的组件完成不同功能。下面定义一个Bean操作的工具类
代码范例:定义一个工具类以实现属性的设置
packagecom.hbsi.BeanTools;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Enumeration;importjavax.servlet.ServletRequest;importcom.hbsi.stringUtils.StringTools;/*by:wzq
time:2017年11月12日*/
public classBeanTools {/*** 这个方法只限制在WEB项目中使用,
* 利用反射进行所有请求参数的设置,要求参数名称要与属性名称保持一致
*@paramobj 要操作的实例化对象
*@paramrequest HttpServletRequeat接口对象实例,目的是为了获得页面的输入参数
*@throwsException*/
public static void setValue(Object obj,ServletRequest request) throwsException {
Enumeration 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代码示例:
packagecom.hbsi.stringUtils;/*by:wzq
time:2017年11月12日*/
public classStringTools {//将字符串转换成大写开头的字母
public staticString toUpperCaseOne(String str) {return str.substring(0,1).toUpperCase().concat(str.substring(1).toLowerCase());
}
}
现在Servlet中的代码就相当简单了,代码示例
packagecom.hbsi.servlet;importjava.io.IOException;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Enumeration;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.hbsi.BeanTools.BeanTools;importjavax.servlet.annotation.WebServlet;/*by:wzq
time:2017年11月12日*/@WebServlet(name= "studentServlet", urlPatterns = { "/studentServlet"})public class StudentServlet extendsHttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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)throwsServletException, 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()
代码示例:取得状态码
packagecom.hbsi.servlet;importjava.io.IOException;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Enumeration;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.hbsi.BeanTools.BeanTools;importjavax.servlet.annotation.WebServlet;/*by:wzq
time:2017年11月12日*/@WebServlet(name= "employeeServlet", urlPatterns = { "/EmployeeServlet/*"})public class EmployeeServlet extendsHttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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)throwsServletException, IOException {this.doGet(request, response);
}
}
执行结果:update
对于所有的操作方法上都可以发现,操作的状态就是方法名称
代码示例:解决代码调用
packagecom.hbsi.servlet;importjava.io.IOException;importjava.lang.reflect.Method;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.annotation.WebServlet;/*by:wzq
time:2017年11月13日*/@WebServlet(name= "dispatchaerServlet", urlPatterns = { "/DispatchaerServlet/*"})public class DispatchaerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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)throwsServletException, IOException {
System.out.println("执行插入方法");
}public void delete(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {
System.out.println("执行删除方法");
}public void update(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {
System.out.println("执行更新方法");
}protected void doPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {this.doGet(request, response);
}
}
执行结果:insert 执行插入方法
在上述代码中method.invoke(this, request,response);需要区分参数是比较麻烦的,而且必须是需要匹配好后才可以调用
以上的代码调用严格来讲算是一种习惯,因为各个方法里面需要有request,response等对象但是也同时感觉到,麻烦程度很高,比如需要知道参数的个数。
如果不想做参数的判断,如果说现在像insert(),update()等操作,那些地方可能使用到request或者response,接收参数,跳转,
代码优化:
packagecom.hbsi.servlet;importjava.io.IOException;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importjavax.servlet.annotation.WebServlet;/*by:wzq
time:2017年11月13日*/@WebServlet(name= "dispatchaerServlet", urlPatterns = { "/DispatchaerServlet/*"})public class DispatchaerServlet extendsHttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, 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);
}publicString insert(){
System.out.println("执行插入方法");return "/insert.jsp";
}publicString delete() {
System.out.println("执行删除方法");return "/delete.jsp";
}publicString update() {
System.out.println("执行更新方法");return "/update.jsp";
}protected void doPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {this.doGet(request, response);
}
}
执行结果:执行插入方法
此时Servlet已经可以反射调用,而且也可以反射将表单的参数设置给属性。
总结:关于反射设置数据内容的情况
代码示例:定义三个类,Emp,Dept,Company,三个类相关联
Emp> Dept > Company
代码实现功能:可以深层的为对象的属性赋值,
EMP属性:
privateInteger empid;privateString empname;private Dept dept = new Dept();
Dept属性:
privateInteger deptid;privateString deptname;private Company company = new Company();
Company属性:
privateInteger companyid;private String companyname;
工具类StringFirstUPTools:
//作用就是将制定字符串的首字母大写处理
public staticString stringFirstUP(String str) {return str.substring(0, 1).toUpperCase()+str.substring(1,str.length());
}
核心代码实现:注意不适用于自身赋值
packagecom.hbsi.servlet;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importcom.hbsi.domain.Emp;/*by:wzq
time:2017年11月18日*/
public classServlet {//emp属性操作需要当前类对象完成//emp.dept属性需要由emp类对象完成
private String requestParamName = "emp.dept.deptid";//模拟多级赋值的操作的参数
private String value = "6666";private Emp emp = new Emp();//必须有实例化对象
publicEmp getEmp() {returnemp;
}public void handleParam(String paramName,String value) throwsException {
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
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 voidmain(String[] args) {newServlet().get();
}
}
执行结果 : 6666
使用此类操作可以无限制进行数据的赋值,排除自关联的情况
ClassLoader类
当使用java命令解释程序的时候,会自动根据CLASSPATH加载所需要的类文件,而用户现在要也可以编写自己的类加载器。
在Class类里面默认定义有专门的取得一个类的类加载器的方法
取得类加载器:public ClassLoader getClassLoader() 返回类的类加载器。
public classClassLoderDemo {public static voidmain(String[] args) {
ClassLoderDemo classLoderDemo= newClassLoderDemo();
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 extendsClassLoader{
@Overridepublic Class> loadClass(String arg0) throwsClassNotFoundException {return super.loadClass(arg0);//直接调用父类的loadClass()方法
}public static void main(String[] args) throwsException {
MyClassLoader myClassLoader= newMyClassLoader();
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盘根目录下,
packagecom.hbsi.domain;public classStudent {publicStudent() {
System.out.println("student 实例化");
}
@OverridepublicString toString() {return "Student 学生信息 toString()";
}
}
实现自定义类加载器,---加载文件数据
packagecom.hbsi.servlet;importjava.io.ByteArrayOutputStream;importjava.io.File;importjava.io.FileInputStream;importjava.io.InputStream;public class ClassLoderDemo extendsClassLoader{public static voidmain(String[] args) {try{
ClassLoderDemo classLoderDemo= newClassLoderDemo();
classLoderDemo.loadClassFile("com.hbsi.domain.Student");//参数必须是包点类名
} catch(Exception e) {
e.printStackTrace();
}
}public voidloadClassFile(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) throwsException{
String[] split= className.split("\\.");//拆分
String name = split[split.length-1];//取的Class类名
File file = new File("D:/"+name+".class");//拼接路径//内存输出流
ByteArrayOutputStream arrayOutputStream = newByteArrayOutputStream();//字节流
InputStream inputStream = newFileInputStream(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();returnbyteArray;
}
}
执行结果: 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包中,如下代码,
packagecom.hbsi.BeanTools;importjava.io.ByteArrayOutputStream;importjava.io.InputStream;importjava.net.URL;importjava.net.URLConnection;public class ClassLoderDemo extendsClassLoader{public static voidmain(String[] args) {try{
ClassLoderDemo classLoderDemo= newClassLoderDemo();
classLoderDemo.loadClassFile("com.hbsi.domain.Student");//参数必须是包点类名
} catch(Exception e) {
e.printStackTrace();
}
}public voidloadClassFile(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) throwsException{
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 = newByteArrayOutputStream();//字节流
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();returnbyteArray;
}
}
以及Student.class的存放目录
执行结果:
student 实例化
Student 学生信息 toString()
在进行类加载的过程之中存在一种概念 -- 双亲加载:如果是系统类则会由系统的类加载器进行加载,例如如果现在加载的是java.lang.String,那么这个类会在程序运行时自动完成加载,而后如果用户再以同样的名称加载了自定义的java.lang.String,那么在系统之中就会做出一个检测, 如果检测出了一个问题,则无法加载,会出现错误提示。
java 分析类_java--分析简单java类与反射的联系相关推荐
- java mysql 操作类_Java 数据库简单操作类
1 packagecom.latiny.db;2 3 import java.io.*;4 import java.sql.*;5 importjava.util.ArrayList;6 import ...
- java rectangle 单位_Java作业(创建Rectangle类).doc
<Java语言>课程作业 (第一次) 题 目 学 院 专 业 班 别 学 号 姓 名 2010年10月8日 一.课程题目 12.创建一个名为Rectangle的类来表示一个使用宽度和高度来 ...
- java怎么创建日期类_java中的日期类Date
一.Java中的日期概述 日期在Java中是一块非常复杂的内容,对于一个日期在不同的语言国别环境中,日期的国际化,日期和时间之间的转换,日期的加减运算,日期的展示格式都是非常复杂的问题. 在Java中 ...
- java源程序可以有几个主类_Java源程序是由类定义组成的,每个程序可以定义若干个类,但只有一个类是主类。_学小易找答案...
[填空题]分析以下程序的执行结果 #include using namespace std; class Sample { int x; int y; public: Sample(int a,int ...
- java 静态类 安全_Java静态static工具类线程安全问题研究
针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...
- java泛型方法 通配符_Java泛型教程–示例类,接口,方法,通配符等
java泛型方法 通配符 泛型是Java编程的核心功能之一,它是Java 5中引入的.如果您使用的是Java Collections ,并且版本5或更高版本,则可以肯定使用了它. 将泛型与集合类一起使 ...
- java中检查性异常类_Java异常处理、java语言推崇使用检查类型异常
异常处理是java语言的重要特性之一,<Three Rules for effective Exception Handling>一文中是这么解释的:它主要帮助我们在debug的过程中解决 ...
- java中的祖先类_Java程序公共祖先类-Object
在Java中,所有的类都继承自Object类,它是所有的始祖,但是我们不需要显示的书写extends Object. equals方法 在JDK中,Object类的equals方法的实现如下: pub ...
- java的string类_Java中的String类笔记
说明 源码 //jdk8 public final class String implements java.io.Serializable, Comparable, CharSequence { / ...
最新文章
- C++ 排序函数 sort(),qsort()的用法 附加.str()用法
- lodop打印不显示页码_Lodop插件实现打印功能
- div跳转html页面底部,即使没有内容,如何强制DIV块扩展到页面底部?
- dellt服务器r修复,RE: 求助 Dell T 310服务器蓝屏
- java多线程知识汇总(三)如何选择锁?如何加锁
- 那个分分钟处理 10 亿节点图计算的 Plato,现在怎么样了?
- 实用js小汇总--获取服务器控件ID
- 2021-07-03父传递子,子传递父,选项激活自定义组件
- 基于AD09的四层板设计概要
- java中观察者模式的使用场景
- linux进程内存大于4g,linux支持大于4G内存
- xilinx官网下载vivado速度慢的解决方法(适用于所有版本)
- word论文排版和写作01:样式、自动列表、图片、表格、公式、脚注、目录、页眉页脚及各种交叉引用
- 华为早几年的服务器型号,云服务器一般用几年
- win10免费sdk安装详细过程
- 暴露在公网环境下主机的安全防护
- java 继承extends
- 市场上股票接盘合作,大宗交易锁仓返点资源变现渠道
- HTML实训实训心得
- 【腾讯开放平台】Android、IOS实现指定QQ临时会话功能