分析简单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类与反射的联系相关推荐

  1. java mysql 操作类_Java 数据库简单操作类

    1 packagecom.latiny.db;2 3 import java.io.*;4 import java.sql.*;5 importjava.util.ArrayList;6 import ...

  2. java rectangle 单位_Java作业(创建Rectangle类).doc

    <Java语言>课程作业 (第一次) 题 目 学 院 专 业 班 别 学 号 姓 名 2010年10月8日 一.课程题目 12.创建一个名为Rectangle的类来表示一个使用宽度和高度来 ...

  3. java怎么创建日期类_java中的日期类Date

    一.Java中的日期概述 日期在Java中是一块非常复杂的内容,对于一个日期在不同的语言国别环境中,日期的国际化,日期和时间之间的转换,日期的加减运算,日期的展示格式都是非常复杂的问题. 在Java中 ...

  4. java源程序可以有几个主类_Java源程序是由类定义组成的,每个程序可以定义若干个类,但只有一个类是主类。_学小易找答案...

    [填空题]分析以下程序的执行结果 #include using namespace std; class Sample { int x; int y; public: Sample(int a,int ...

  5. java 静态类 安全_Java静态static工具类线程安全问题研究

    针对静态方法有以下一些前提: 静态方法和实例方法的区别是静态方法只能引用静态变量,静态方法通过类名来调用,实例方法通过对象实例来调用 每个线程都有自己的线程栈,栈与线程同时创建,每一个虚拟机线程都有自 ...

  6. java泛型方法 通配符_Java泛型教程–示例类,接口,方法,通配符等

    java泛型方法 通配符 泛型是Java编程的核心功能之一,它是Java 5中引入的.如果您使用的是Java Collections ,并且版本5或更高版本,则可以肯定使用了它. 将泛型与集合类一起使 ...

  7. java中检查性异常类_Java异常处理、java语言推崇使用检查类型异常

    异常处理是java语言的重要特性之一,<Three Rules for effective Exception Handling>一文中是这么解释的:它主要帮助我们在debug的过程中解决 ...

  8. java中的祖先类_Java程序公共祖先类-Object

    在Java中,所有的类都继承自Object类,它是所有的始祖,但是我们不需要显示的书写extends Object. equals方法 在JDK中,Object类的equals方法的实现如下: pub ...

  9. java的string类_Java中的String类笔记

    说明 源码 //jdk8 public final class String implements java.io.Serializable, Comparable, CharSequence { / ...

最新文章

  1. C++ 排序函数 sort(),qsort()的用法 附加.str()用法
  2. lodop打印不显示页码_Lodop插件实现打印功能
  3. div跳转html页面底部,即使没有内容,如何强制DIV块扩展到页面底部?
  4. dellt服务器r修复,RE: 求助 Dell T 310服务器蓝屏
  5. java多线程知识汇总(三)如何选择锁?如何加锁
  6. 那个分分钟处理 10 亿节点图计算的 Plato,现在怎么样了?
  7. 实用js小汇总--获取服务器控件ID
  8. 2021-07-03父传递子,子传递父,选项激活自定义组件
  9. 基于AD09的四层板设计概要
  10. java中观察者模式的使用场景
  11. linux进程内存大于4g,linux支持大于4G内存
  12. xilinx官网下载vivado速度慢的解决方法(适用于所有版本)
  13. word论文排版和写作01:样式、自动列表、图片、表格、公式、脚注、目录、页眉页脚及各种交叉引用
  14. 华为早几年的服务器型号,云服务器一般用几年
  15. win10免费sdk安装详细过程
  16. 暴露在公网环境下主机的安全防护
  17. java 继承extends
  18. 市场上股票接盘合作,大宗交易锁仓返点资源变现渠道
  19. HTML实训实训心得
  20. 【腾讯开放平台】Android、IOS实现指定QQ临时会话功能

热门文章

  1. 第一次拼命的跟别人挤,找明星签名!!!
  2. 王思聪麾下的HR,被刷屏了!
  3. 关于DOS命令的骚操作
  4. 关于博客搬家至博客园的通知
  5. php越权执行命令漏洞_PHP漏洞挖掘思路+实例 第二章
  6. 06 | 职位描述(JD)不是摆设,看懂招聘岗位
  7. GPS模块资料,链接
  8. c语言循环中按键跳出,C语言跳出循环
  9. forEach for 循环跳出问题
  10. 飞行控制系统中速度的表示