Day16基礎(chǔ)不牢地動山搖-Java基礎(chǔ)
1、反射機制
反射機制如果只是針對普通開發(fā)者而言意義不大,一般都是作為一些系統(tǒng)的構(gòu)架設(shè)計去使用的,包括以后學(xué)習(xí)的開源框架,那么幾乎都是反射機制。
1.1 認(rèn)識反射
反射指的是對象的反向處理操作,就首先觀察以下“正”的操作,在默認(rèn)情況下,必須先導(dǎo)入一個包才能產(chǎn)生類的實例化對象。
所謂的“反”根據(jù)對象來取得對象的來源信息,“反”的操作的本來來源就是Object的一個方法。
- 取得class對象:public final 類<?> getClass() 該方法返回的一個Class類的對象,這個Class描述的就是類。
package com.day16.demo;
import java.util.Date;
import javafx.scene.chart.PieChart.Data;
public class FanShedemo {
public static void main(String[] args) {
Date date = new Date();
//java.util.Date
System.out.println(date.getClass().getName());
}
}
此時通過對象的確對象的來源,就是“反”的本質(zhì)。在反射的背后不在是一個對象,而是對象身后的來源。
而這個getClass()方法返回的對象是Class類對象,所以這個Class就是所有反射操作的源頭,但是在講解其真正使用之前還有一個需要先解釋的問題,既然Class是所有反射操作的源頭,那么這個類肯定是最為重要的,而如果要想取得這個類的實例化對象,java中定義了三種方式:
方式一:通過Object類的getClass()方法取得
package com.day16.demo;
import java.util.Date;
public class FanShedemo {
public static void main(String[] args) {
Date de = new Date();//正著操作
Class<?> cla =de.getClass();//取得class對象
System.out.println(cla.getName());//反著來
}
}
方式二:通過“類.Class”取得
package com.day16.demo;
import java.util.Date;
public class FanShedemo {
public static void main(String[] args) {
Date de = new Date();//正著操作
Class<?> cla =Date.class;//取得class對象
System.out.println(cla.getName());//反著來
}
}
方式三:使用Class內(nèi)部定義的一個static方法
package com.day16.demo;
import java.util.Date;
public class FanShedemo {
public static void main(String[] args) throws Exception{
Date de = new Date();//正著操作
Class<?> cla =Class.forName("java.util.Date");//取得class對象
System.out.println(cla.getName());//反著來
}
}
在以上給出的三個方法會發(fā)現(xiàn)一個神奇的地方,除了第一種形式會產(chǎn)生Date實例化對象,而第二種和第三種沒有
實例化取得對象。于是取得Class類對象有一個最直接的好處:可以直接通過反射實例化對象,在Class類中有一個方法:
- **通過反射實例化對象:**public T newInstance() throws InstantiationException IllegalAccessException
反射實例化對象
package com.day16.demo;
import java.util.Date;
public class FanShedemo {
public static void main(String[] args) throws Exception{
Class<?> cla =Class.forName("java.util.Date");//取得class對象
Object o = cla.newInstance();//取得Date對象
System.out.println(o);
}
}

現(xiàn)在可以發(fā)現(xiàn),對于對象的實例化操作,除了使用關(guān)鍵字new之外又多了一個反射機制操作,而且這個操作要比之前使用的new復(fù)雜一些,可是有什么用呢?
對于程序的開發(fā)模式之前一直強點:盡量減少耦合,而減少耦合的最好的做法是使用接口,但是就算使用了接口也逃不出關(guān)鍵字new,多以實際上new是耦合的關(guān)鍵元兇。
1.2 取得父類信息
反射可以做出一個對象所具備的所有操作行為,而且最關(guān)鍵的是這一切的操作都可以基于Object類型進行。
在Java里面任何的程序類實際上都一定會有一個父類,在Class類里面就可以通過此類方式來取得父類或者是實現(xiàn)的父接口,有如下兩個方法提供:
| public 軟件包 getPackage() | 取得類的包名稱 |
| public 類<? super T> getSuperclass() | 取得父類的Class對象 |
| public 類<?>[] getInterfaces() | 取得父接口 |
取得類的相關(guān)信息
package com.day16.demo;
import java.util.Arrays;
interface IFruit{}
interface IMessage{}
class Person implements IFruit,IMessage{
}
public class FanShedemo {
public static void main(String[] args) throws Exception{
Class<?> cls = Person.class;
System.out.println(cls.getPackage().getName());
System.out.println(cls.getSuperclass().getName());
Class<?> itf[] = cls.getInterfaces();
System.out.println(Arrays.toString(itf));
}
}
通過我們反射可以取得類結(jié)構(gòu)上的所有關(guān)鍵信息。
1.3 反射調(diào)用構(gòu)造
一個類可以存在多個構(gòu)造方法,如果我們要想取得類中構(gòu)造的調(diào)用,我們就可以使用Class類提供的兩個方法
| public Constructor getConstructor(類<?>… parameterTypes) throws NoSuchMethodException, SecurityException |
取得指定參數(shù)類型的構(gòu)造方法 |
| public Constructor<?>[] getConstructors() throws SecurityException |
取得類中的所有構(gòu)造 |
以上兩個方法的返回類型都是java.lang.reflect.Constructor類的實例化對象,這個類里面關(guān)注一個方法,實例化對象:public T newInstance(Object… initargs) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException
取得類中所有構(gòu)造方法的信息—利用Constructor類中的toString()方法取得了構(gòu)造方法的完整信息
package com.day16.demo;
import java.lang.reflect.Constructor;
import java.util.Arrays;
class Person {
public Person(){}
public Person(String name){}
public Person(String name , int age){}
}
public class FanShedemo {
public static void main(String[] args) throws Exception{
Class<?> cls = Person.class;
Constructor<?> cst [] = cls.getConstructors();
for (int i = 0; i < cst.length; i++) {
System.out.println(cst[i]);
}
}
}
如果使用getName()方法就比較麻煩
自己拼湊構(gòu)造方法操作
package com.day16.demo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
class Person {
public Person() throws Exception,RuntimeException{}
public Person (String name) throws Exception,RuntimeException{}
public Person(String name , int age) throws Exception,RuntimeException{}
}
public class FanShedemo {
public static void main(String[] args) throws Exception{
Class<?> cls = Person.class;
Constructor<?> cst [] = cls.getConstructors();
for (int i = 0; i < cst.length; i++) {
System.out.print(Modifier.toString(cst[i].getModifiers()) + " ");
System.out.print(cst[i].getName() + "(");
Class <?> params [] = cst[i].getParameterTypes();
for (int j = 0; j < params.length; j++) {
System.out.print(params[j].getName());
if(j < params.length - 1){
System.out.print(",");
}
}
System.out.print(")");
Class<?> exps [] = cst[i].getExceptionTypes();
if(exps.length > 0){
System.out.print(" throws ");
for (int j = 0; j < exps.length; j++) {
System.out.print(exps[j].getName());
if(j < exps.length - 1){
System.out.print(",");
}
}
}
System.out.println();
}
}
}
學(xué)習(xí)Constructor類目的并不是分析方法的組成,最需要的關(guān)注就是問題的結(jié)論:在定義簡單的java類一定要保留一個無參構(gòu)造。
觀察沒有無參構(gòu)造的方法
package com.day16.demo;
import java.lang.reflect.Constructor;
class Per{
private String name;
private int age;
public Per(String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Per [name=" + name + ", age=" + age + "]";
}
}
public class FanShedemo {
public static void main(String[] args) throws Exception{
Class<?> cls = Per.class;//取得class對象
Object obj=cls.newInstance();
}
}
Exception in thread "main" java.lang.InstantiationException: com.day16.demo.Person at java.lang.Class.newInstance(Class.java:427) at com.day16.demo.FanShedemo.main(FanShedemo.java:19) Caused by: java.lang.NoSuchMethodException: com.day16.demo.Person.<init>() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.newInstance(Class.java:412) ... 1 more
此時運行的時候出現(xiàn)了錯誤提示“java.lang.InstancetiationException”因為以上的方式使用反射實例化對象時需要的是類之中提供無參構(gòu)造方法,但是現(xiàn)在既然沒有了無參構(gòu)造方法,那么就必須明確的找到一個構(gòu)造方法。
通過Constructor類實例化對象
package com.day16.demo;
import java.lang.reflect.Constructor;
class Per{
private String name;
private int age;
public Per(String name,int age){
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Per [name=" + name + ", age=" + age + "]";
}
}
public class FanShedemo2 {
public static void main(String[] args) throws Exception{
Class<?> cls = Per.class;//取得class對象
//現(xiàn)在明確表示取得指定參數(shù)類型的構(gòu)造方法對象
Constructor<?> cont = cls.getConstructor(String.class,int.class);
System.out.println(cont.newInstance("張三",19));
}
}
一行寫簡單Java類要寫無參構(gòu)造,以上內(nèi)容就只需要了解就可以了。
1.4 反射調(diào)用方法
當(dāng)取得了一個類之中的實例化對象之后,下面最需要調(diào)用的肯定是類之中的方法,所以可以繼續(xù)使用Class類取得一個類中所定義的方法定義:
| **public Method[] getMethods() throws SecurityException |
取得全部方法 |
| public Method getMethod(String name,Class<?>… parameterTypes) throws NoSuchMethodException, SecurityException |
取得指定方法 |
發(fā)現(xiàn)以上的方法返回的都是java.lang.Method類的對象。
取得一個類之中全部定義的方法
package com.day16.demo;
import java.lang.reflect.Method;
class Student{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class FanShedemo3 {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("com.day16.demo.Student");
Method met [] = cls.getMethods();
for (int i = 0; i < met.length; i++) {
System.out.println(met[i]);
}
}
}
但是取得類Method類對象最大的作用不在于方法的列出(方法的列出都在開發(fā)工具上使用了),但是對于取得了Method類對象之后還有一個最大的功能,就是可以利用反射調(diào)用類的方法:
調(diào)用方法:public Object invoke(Object obj,Object… args) throws IllegalAccessException,IllegalArgumentException,InvocationTargetException之前調(diào)用類中的方法的時候使用的都是“對象.方法”,但是現(xiàn)在有了反射之后,可以直接利用Object類調(diào)用指定子類的操作方法。(同事解釋一下,為什么setter,和getter方法的命名要求如此嚴(yán)格)。
利用反射調(diào)用Student類之中的setName(),getName()方法。
package com.day16.demo;
import java.lang.reflect.Method;
class Student{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class FanShedemo3 {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("com.day16.demo.Student");
Object obj = cls.newInstance();//實例化對象
Method met [] = cls.getMethods();
Method setM=cls.getMethod("setName",String.class);//通過反射構(gòu)建方法
Method getM=cls.getMethod("getName");
setM.invoke(obj, "小張同學(xué)");//鍵值對的形式傳遞參數(shù)此過程相當(dāng)于setM
Object result = getM.invoke(obj);
System.out.println(result);
}
}
在日后所有的技術(shù)開發(fā)中,簡單Java類都是如此應(yīng)用,多以必須按照標(biāo)準(zhǔn)進行。
1.5 反射調(diào)用成員
個組成部分就是成員(Field,也可以稱為屬性),如果要通過反射取得類的成員可以使用方法如下:
取得本類的全部成員:public Field[] getDeclaredFields() throws SecurityException
取得指定成員:public Field getDeclaredField(String name)throws NoSuchFieldException, SecurityException
取得本類全部成員
package com.day16.demo;
import java.lang.reflect.Field;
class Person4{
private String name;
}
public class FanShedemo4 {
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("com.day16.demo.Person4");
Object obj = cls.newInstance();
Field[] fields = cls.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
//private java.lang.String com.day16.demo.Person4.name
System.out.println(fields[i]);
}
}
}
但是找到了Field實際上就找到了一個很有意思的操作,在Field類之中提供了兩個方法:
設(shè)置屬性內(nèi)容(類似于:對象.屬性=內(nèi)容):public void set(Object obj,Object value) throws IllegalArgumentException,IllegalAccessException
取得屬性內(nèi)容(類似于:對象.屬性):public Object get(Object obj) throws IllegalArgumentException,IllegalAccessException
可是從類的開發(fā)要求而言,一直都強調(diào)類之中的屬性必須封裝,所以現(xiàn)在調(diào)用之前要想辦法解除封裝。
- 解除封裝(重點):public void setAccessible(boolean flag)throws SecurityException
利用反射操作類中的屬性
package com.day16.demo;
import java.lang.reflect.Field;
class Person4{
private String name;
}
public class FanShedemo4 {
public static void main(String[] args) throws Exception{
Class<?> cls = Class.forName("com.day16.demo.Person4");
Object obj = cls.newInstance();
Field field = cls.getDeclaredField("name");//得到Person4成員變量
//由于Person4設(shè)置的屬性是私有屬性,所以是無法操作的
field.setAccessible(true);///解決封裝
field.set(obj, "小張");
System.out.println(field.get(obj));
}
}
雖然反射機制運行直接操作類之中的屬性,可是不會有任何一種程序直接操作屬性,都會通過setter,getter方法。

1.6 反射與簡單Java類—單級VO操作原理
如果現(xiàn)在又一個簡單Java類,那么這個簡單Java類中的屬性按照原始的做法一定要通過setter才可以設(shè)置,取得肯定繼續(xù)使用getter(不關(guān)注此處)。
Emp.java
package com.day16.vo;
public class Emp {
private String ename;
private String job;
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
@Override
public String toString() {
return "Emp [ename=" + ename + ", job=" + job + "]";
}
}
EmpAction.java
package com.day16.action;
import com.day16.vo.Emp;
public class EmpAction {
private Emp emp = new Emp();
public void setValue(String val ){//設(shè)置屬性內(nèi)容
this.emp.setEname("SMI");
this.emp.setJob("STRACK");
}
public Emp getEmp(){
return emp;
}
}
EmpDemo.java
package com.day16.demo;
import com.day16.action.EmpAction;
public class EmpDemo {
public static void main(String[] args) {
String value="emp.ename:smi|emp.job:strack";
EmpAction action = new EmpAction();
action.setValue(value);
System.out.println(action.getEmp());
}
}

1.7 單極自動VO設(shè)置實現(xiàn)
現(xiàn)在所有操作都是通過TestDemo類調(diào)用EmpAciton類實現(xiàn)的,而EmpAciton類的主要作用在于定位要操作屬性的類型。同時該程序應(yīng)該符合所有的簡單Java類開發(fā)形式,也就意味著我們的設(shè)計必須有一個單獨的類來實現(xiàn)。
由于Bean的處理操作肯定需要重復(fù)出去對象信息,所以我們還需要準(zhǔn)備兩個程序類:StringUtils,負(fù)責(zé)字符串的操作,畢竟屬性的首字母需要大寫處理,而后在寫一個對象的具體操作(取得對象、設(shè)置對象內(nèi)容)。
工具類—BeanOperation.java
package com.day16.util;
/**
* @author 張晟睿
* 本類主要負(fù)責(zé)實現(xiàn)自動VO匹配處理操作,本身不需要通過實例化對象完成,所以構(gòu)造方法私有化
*/
public class BeanOperation {
private BeanOperation(){}
/**
* @param actionObject 表示當(dāng)前發(fā)出設(shè)置請求的程序類的當(dāng)前對象
* @param msg 所有屬性的具體內(nèi)容,格式“屬性名稱:內(nèi)容|屬性名稱:內(nèi)容”
*
*/
public static void setBeanValue(Object actionObject,String msg) throws Exception{
String result [] = msg.split("\\|");
for (int i = 0; i < result.length; i++) {
//需要針對于給定的屬性名稱和內(nèi)容進行一次拆分
String temp[] = result[i].split(":");
String attribute = temp[0];//屬性名稱,包括“XxxAction屬性和具體的簡單AJava類的屬性”
String value = temp[1];//接收具體的內(nèi)容屬性
String fields [] = attribute.split("\\.");
Object currentObject = ObjectUtils.getObject(actionObject,fields[0]);
ObjectUtils.setObjectValue(currentObject, fields[1], value);
}
}
}
工具類—StringUtils.java
package com.day16.util;
/**
* @author 張晟睿
* 針對于字符串進行處理操作
*/
public class StringUtils {
private StringUtils(){}
/**
* @param str
* @return 返回首字母大寫
* 首字母大寫
*/
public static String initcap(String str){
return str.substring(0,1).toUpperCase() + str.substring(1);
}
}
工具類—ObjectUtils.java
package com.day16.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @author 張晟睿
* 本類的主要功能是根據(jù)屬性名稱調(diào)用響應(yīng)類中g(shù)etter、setter方法
*/
public class ObjectUtils {
private ObjectUtils(){}
/**
* 根據(jù)指定的類對象,設(shè)置類中的屬性
* @param wrapo 屬性所在類的實例化對象
* @param attribute 屬性名稱
* @param value 屬性內(nèi)容
*/
public static void setObjectValue(Object wrapo,String attribute, String value) throws Exception{
//調(diào)用指定屬性的Field對象,母的是取得對象類型,如果沒有屬性也就是說該操作無法繼續(xù)
Field field = wrapo.getClass().getDeclaredField(attribute);//判斷屬性是否存在
if(field == null){
field = wrapo.getClass().getField(attribute);
}
if(field == null){//兩次操作都無法取得對應(yīng)的成員變量
return ;//該屬性一定不存在
}
String methodName = "set" + StringUtils.initcap(attribute);
Method method = wrapo.getClass().getMethod(methodName,field.getType());
method.invoke(wrapo, value);
}
/**
* 負(fù)責(zé)調(diào)用指定類中g(shù)etter方法
* @param wrapo 表示要調(diào)用方法的所在對象
* @param attribute 表示屬性名稱
* @return 調(diào)用對象的結(jié)果
*/
public static Object getObject(Object wrapo,String attribute) throws Exception{
String methodName = "get" + StringUtils.initcap(attribute);//定義getter方法
//調(diào)用指定屬性的Field對象,母的是取得對象類型,如果沒有屬性也就是說該操作無法繼續(xù)
Field field = wrapo.getClass().getDeclaredField(attribute);
if(field == null){
field = wrapo.getClass().getField(attribute);
}
if(field == null){//兩次操作都無法取得對應(yīng)的成員變量
return null;//該屬性一定不存在
}
Method method = wrapo.getClass().getMethod(methodName);
return method.invoke(wrapo);
}
}
EmpAction.java
package com.day16.action;
import com.day16.util.BeanOperation;
import com.day16.vo.Emp;
public class EmpAction {
private Emp emp = new Emp();
public void setValue(String val ){//設(shè)置屬性內(nèi)容
//之所以傳遞this,主要將EmpAction的類對象傳遞方法里面
//因為給定的標(biāo)記:emp.ename:smith,而emp應(yīng)該對象的是getEmp()方法
try {
BeanOperation.setBeanValue(this, val);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Emp getEmp(){
return emp;
}
}

1.8 反射與簡單Java類—多級VO設(shè)置實現(xiàn)

現(xiàn)在假設(shè)一個雇員屬于一個部門,一個部門屬于一個公司,一個公司屬于一個城市,一個城市屬于一個省份,一個省份屬于一個國家,這種類似關(guān)系都可以通過字符串實現(xiàn)多級配置。
修改Dept.java類
public class Dept {
private String dname;
private String loc;
private Company company = new Company();
}
修改Emp.java類
public class Emp {
private String ename;
private String job;
private Dept dept = new Dept();
}
此時所有的引用關(guān)系上都自動進行了對象實例化。而現(xiàn)在程序希望可以滿足于單級和多級。

修改BeanOperation.java
package com.day16.util;
/**
* @author 張晟睿
* 本類主要負(fù)責(zé)實現(xiàn)自動VO匹配處理操作,本身不需要通過實例化對象完成,所以構(gòu)造方法私有化
*/
public class BeanOperation {
private BeanOperation(){}
/**
* @param actionObject 表示當(dāng)前發(fā)出設(shè)置請求的程序類的當(dāng)前對象
* @param msg 所有屬性的具體內(nèi)容,格式“屬性名稱:內(nèi)容|屬性名稱:內(nèi)容”
*
*/
public static void setBeanValue(Object actionObject,String msg) throws Exception{
String result [] = msg.split("\\|");
for (int i = 0; i < result.length; i++) {
//需要針對于給定的屬性名稱和內(nèi)容進行一次拆分
String temp[] = result[i].split(":");
String attribute = temp[0];//屬性名稱,包括“XxxAction屬性和具體的簡單AJava類的屬性”
String value = temp[1];//接收具體的內(nèi)容屬性
String fields [] = attribute.split("\\.");//拆分出屬性信息
if(fields.length > 2){//多級配置
//如果要想多級確定出屬性的操作對象,那么應(yīng)該一層找出每一個getter方法返回的內(nèi)容
Object currentObject = actionObject;//確定當(dāng)前要操作的對象
for (int j = 0; j < fields.length - 1; j++) {//對應(yīng)getter返回對象
currentObject = ObjectUtils.getObject(currentObject, fields[j]);
}
ObjectUtils.setObjectValue(currentObject, fields[fields.length - 1], value);
}else{//單級配置
Object currentObject = ObjectUtils.getObject(actionObject,fields[0]);
ObjectUtils.setObjectValue(currentObject, fields[1], value);
}
}
}
}
定義TestEmpDemo.java
package com.day16.demo;
import com.day16.action.EmpAction;
public class TestEmpDemo {
public static void main(String[] args) {
String value="emp.ename:smi|emp.job:strack|emp.dept.dname:財務(wù)部|emp.dept.company.name:zsr|emp.dept.company.address:北京";
EmpAction action = new EmpAction();
action.setValue(value);
System.out.println(action.getEmp());
}
}
這樣的程序才可以正常使用,屬于無限級配置。
2、ClassLoader類加載器
Class類描述的是類的整個信息,在Class類中提供的forName()方法它所能處理的只是通過CLASSPATH配置的路徑進行加載,而我們的類加載的路徑可能是網(wǎng)絡(luò)、文件、數(shù)據(jù)庫。這是ClassLoader類主要作用。
2.1 認(rèn)識類加載器
首先Class觀察一個方法:public ClassLoader getClassLoader();
編寫簡單的反射程序,觀察ClassLoader的存在
package com.day17.demo;
class Member{//自定義類一定在CLASSPATH之中
}
public class TestDemo1 {
public static void main(String[] args) {
Class<?> cls = Member.class;
System.out.println(cls.getClassLoader());
System.out.println(cls.getClassLoader().getParent());
System.out.println(cls.getClassLoader().getParent().getParent());
}
}
/*
sun.misc.Launcher$AppClassLoader@73d16e93
sun.misc.Launcher$ExtClassLoader@15db9742
null
*/
出現(xiàn)兩個加載器AppClassLoader(應(yīng)用程序類加載器)、ExtClassLoader(擴展類加載器)。

對于第三方程序類庫除了CLASSPATH之外,實際上在java里面還有一個加載目錄:C:\ProgramFiles\Java\jdk1.8.0_241\jre\lib\ext

觀察類我們發(fā)現(xiàn)ClassLoader里有一個方法:public 類<?> loadClass(String name) throws ClassNotFoundException,進行類的加載操作處理。
2.2 自定義ClassLoader
**實現(xiàn)文件的類加載器 **
package com.day17.demo;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
class MyClassLoader extends ClassLoader{
/**
* 實現(xiàn)一個自定義的類加載器,傳入類名稱后,通過指定文件路徑加載
* @param className
* @return
* @throws Exception
*/
public Class<?> loadData(String className) throws Exception{
byte classDate [] = this.loadClassData();
return super.defineClass(className, classDate, 0, classDate.length);
}
/**
* 通過指定文件路徑進行類的文件加載,進行二進制讀取
* @return
* @throws Exception
*/
private byte [] loadClassData() throws Exception{
InputStream input = new FileInputStream("f:" + File.separator + "java" + File.separator + "Member.class");
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] data = new byte [20];//定義讀取的緩沖區(qū)
int temp = 0;
while((temp = input.read(data)) != -1){
bos.write(data,0,temp);
}
byte ret [] = bos.toByteArray();
input.close();
bos.close();
return ret;
}
}
public class ClassLoaderDemo {
public static void main(String[] args) throws Exception{
Class<?> cls = new MyClassLoader().loadData("com.day17.test.Member");
System.out.println(cls.newInstance());
}
}
類加載器給我們用戶最大的幫助就是在于可以通過動態(tài)的路徑實現(xiàn)類的加載處理操作。
到此這篇關(guān)于Day16基礎(chǔ)不牢地動山搖-Java基礎(chǔ)的文章就介紹到這了,更多相關(guān)Java基礎(chǔ)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring深入分析講解BeanUtils的實現(xiàn)
java知識體系統(tǒng)有很多數(shù)據(jù)實體,比較常用的DTO、BO、DO、VO等,其他類似POJO概念太老了現(xiàn)在基本廢棄掉了,本篇幅直接忽略,對于這幾種數(shù)據(jù)實體各自代表的含義和應(yīng)用場景先做一下簡單描述和分析2022-06-06
springboot結(jié)合maven配置不同環(huán)境的profile方式
這篇文章主要介紹了springboot結(jié)合maven配置不同環(huán)境的profile方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
JavaWeb核心技術(shù)中Session與Cookie淺析
session的工作原理和cookie非常類似,在cookie中存放一個sessionID,真實的數(shù)據(jù)存放在服務(wù)器端,客戶端每次發(fā)送請求的時候帶上sessionID,服務(wù)端根據(jù)sessionID進行數(shù)據(jù)的響應(yīng)2023-02-02
IDEA報錯:Process terminated的問題及解決
這篇文章主要介紹了IDEA報錯:Process terminated的問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
SpringBoot3.x版本與Mybatis-Plus不兼容問題
當(dāng)使用3.x版本的SpringBoot結(jié)合Mybatis-Plus時版本不兼容就會報錯,本文就來介紹一下這個問題的解決方法,感興趣的可以了解一下2024-03-03
java警告:源發(fā)行版17 需要目標(biāo)發(fā)行版17問題及解決
文章介紹了如何解決項目JDK版本不一致的問題,包括修改Project Structure、Modules、Dependencies和Settings中的JDK版本,以及在pom.xml中指定JDK源版本2024-11-11
Java實現(xiàn)將String轉(zhuǎn)化為Int
這篇文章主要介紹了Java實現(xiàn)將String轉(zhuǎn)化為Int方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-05-05

