亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Day16基礎(chǔ)不牢地動山搖-Java基礎(chǔ)

 更新時間:2021年08月23日 11:49:58   作者:zsr6135  
這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、反射機(jī)制

反射機(jī)制如果只是針對普通開發(fā)者而言意義不大,一般都是作為一些系統(tǒng)的構(gòu)架設(shè)計(jì)去使用的,包括以后學(xué)習(xí)的開源框架,那么幾乎都是反射機(jī)制。

1.1 認(rèn)識反射

反射指的是對象的反向處理操作,就首先觀察以下“正”的操作,在默認(rèn)情況下,必須先導(dǎo)入一個包才能產(chǎn)生類的實(shí)例化對象。

所謂的“反”根據(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是所有反射操作的源頭,那么這個類肯定是最為重要的,而如果要想取得這個類的實(shí)例化對象,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實(shí)例化對象,而第二種和第三種沒有

實(shí)例化取得對象。于是取得Class類對象有一個最直接的好處:可以直接通過反射實(shí)例化對象,在Class類中有一個方法:

  • **通過反射實(shí)例化對象:**public T newInstance() throws InstantiationException IllegalAccessException

反射實(shí)例化對象

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);
	}
}

image-20210821155437468

現(xiàn)在可以發(fā)現(xiàn),對于對象的實(shí)例化操作,除了使用關(guān)鍵字new之外又多了一個反射機(jī)制操作,而且這個操作要比之前使用的new復(fù)雜一些,可是有什么用呢?

對于程序的開發(fā)模式之前一直強(qiáng)點(diǎn):盡量減少耦合,而減少耦合的最好的做法是使用接口,但是就算使用了接口也逃不出關(guān)鍵字new,多以實(shí)際上new是耦合的關(guān)鍵元兇。

1.2 取得父類信息

反射可以做出一個對象所具備的所有操作行為,而且最關(guān)鍵的是這一切的操作都可以基于Object類型進(jìn)行。

在Java里面任何的程序類實(shí)際上都一定會有一個父類,在Class類里面就可以通過此類方式來取得父類或者是實(shí)現(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類的實(shí)例化對象,這個類里面關(guān)注一個方法,實(shí)例化對象: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

此時運(yùn)行的時候出現(xiàn)了錯誤提示“java.lang.InstancetiationException”因?yàn)橐陨系姆绞绞褂梅瓷鋵?shí)例化對象時需要的是類之中提供無參構(gòu)造方法,但是現(xiàn)在既然沒有了無參構(gòu)造方法,那么就必須明確的找到一個構(gòu)造方法。

通過Constructor類實(shí)例化對象

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)取得了一個類之中的實(shí)例化對象之后,下面最需要調(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();//實(shí)例化對象
   	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)進(jì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實(shí)際上就找到了一個很有意思的操作,在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ā)要求而言,一直都強(qiáng)調(diào)類之中的屬性必須封裝,所以現(xiàn)在調(diào)用之前要想辦法解除封裝。

  • 解除封裝(重點(diǎn)):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));
	}
}

雖然反射機(jī)制運(yùn)行直接操作類之中的屬性,可是不會有任何一種程序直接操作屬性,都會通過setter,getter方法。

image-20210821202523981

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());
	}
}

image-20210821211538647

1.7 單極自動VO設(shè)置實(shí)現(xiàn)

現(xiàn)在所有操作都是通過TestDemo類調(diào)用EmpAciton類實(shí)現(xiàn)的,而EmpAciton類的主要作用在于定位要操作屬性的類型。同時該程序應(yīng)該符合所有的簡單Java類開發(fā)形式,也就意味著我們的設(shè)計(jì)必須有一個單獨(dú)的類來實(shí)現(xiàn)。

由于Bean的處理操作肯定需要重復(fù)出去對象信息,所以我們還需要準(zhǔn)備兩個程序類:StringUtils,負(fù)責(zé)字符串的操作,畢竟屬性的首字母需要大寫處理,而后在寫一個對象的具體操作(取得對象、設(shè)置對象內(nèi)容)。

工具類—BeanOperation.java

package com.day16.util;

/**
 * @author 張晟睿
 *	本類主要負(fù)責(zé)實(shí)現(xiàn)自動VO匹配處理操作,本身不需要通過實(shí)例化對象完成,所以構(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)容進(jìn)行一次拆分
			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 張晟睿
 *	針對于字符串進(jìn)行處理操作
 */
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 屬性所在類的實(shí)例化對象
	 * @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的類對象傳遞方法里面
		//因?yàn)榻o定的標(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;
	}
}

image-20210822083531155

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

image-20210822084050435

現(xiàn)在假設(shè)一個雇員屬于一個部門,一個部門屬于一個公司,一個公司屬于一個城市,一個城市屬于一個省份,一個省份屬于一個國家,這種類似關(guān)系都可以通過字符串實(shí)現(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)系上都自動進(jìn)行了對象實(shí)例化。而現(xiàn)在程序希望可以滿足于單級和多級。

image-20210822122022038

修改BeanOperation.java

package com.day16.util;

/**
 * @author 張晟睿
 *	本類主要負(fù)責(zé)實(shí)現(xiàn)自動VO匹配處理操作,本身不需要通過實(shí)例化對象完成,所以構(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)容進(jìn)行一次拆分
			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:財(cái)務(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配置的路徑進(jìn)行加載,而我們的類加載的路徑可能是網(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(擴(kuò)展類加載器)。

image-20210822132640087

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

image-20210822133615839

觀察類我們發(fā)現(xiàn)ClassLoader里有一個方法:public 類<?> loadClass(String name) throws ClassNotFoundException,進(jìn)行類的加載操作處理。

2.2 自定義ClassLoader

**實(shí)現(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{
	/**
	 * 實(shí)現(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);
		
	}
	/**
	 * 通過指定文件路徑進(jìn)行類的文件加載,進(jìn)行二進(jìn)制讀取
	 * @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)的路徑實(shí)現(xiàn)類的加載處理操作。

到此這篇關(guān)于Day16基礎(chǔ)不牢地動山搖-Java基礎(chǔ)的文章就介紹到這了,更多相關(guān)Java基礎(chǔ)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Security 控制授權(quán)的方法

    Spring Security 控制授權(quán)的方法

    本篇文章主要介紹了Spring Security 控制授權(quán)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java文件IO操作教程之DirectIO的意義

    Java文件IO操作教程之DirectIO的意義

    這篇文章主要給大家介紹了關(guān)于Java文件IO操作教程之DirectIO的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 詳解Spring中的@PropertySource注解使用

    詳解Spring中的@PropertySource注解使用

    這篇文章主要介紹了Spring的@PropertySource注解使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • Java中TypeReference用法詳情說明

    Java中TypeReference用法詳情說明

    這篇文章主要介紹了Java中TypeReference用法詳情說明,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-07-07
  • Java多線程中的Balking模式詳解

    Java多線程中的Balking模式詳解

    大家好,本篇文章主要講的是Java多線程中的Balking模式詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • 解決RedisTemplate存儲至緩存數(shù)據(jù)出現(xiàn)亂碼的情況

    解決RedisTemplate存儲至緩存數(shù)據(jù)出現(xiàn)亂碼的情況

    這篇文章主要介紹了解決RedisTemplate存儲至緩存數(shù)據(jù)出現(xiàn)亂碼的情況,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • Java中HTTP接口請求重試的實(shí)現(xiàn)方式

    Java中HTTP接口請求重試的實(shí)現(xiàn)方式

    HTTP接口請求重試是指在請求失敗時,再次發(fā)起請求的機(jī)制,在實(shí)際應(yīng)用中,由于網(wǎng)絡(luò)波動、服務(wù)器故障等原因,HTTP接口請求可能會失敗,為了保證系統(tǒng)的可用性和穩(wěn)定性,需要對HTTP接口請求進(jìn)行重試,所以本文給大家介紹了HTTP接口請求重試的實(shí)現(xiàn)方式,需要的朋友可以參考下
    2024-01-01
  • 帶你輕松搞定Java面向?qū)ο蟮木幊?-數(shù)組,集合框架

    帶你輕松搞定Java面向?qū)ο蟮木幊?-數(shù)組,集合框架

    Java是面向?qū)ο蟮母呒壘幊陶Z言,類和對象是 Java程序的構(gòu)成核心。圍繞著Java類和Java對象,有三大基本特性:封裝是Java 類的編寫規(guī)范、繼承是類與類之間聯(lián)系的一種形式、而多態(tài)為系統(tǒng)組件或模塊之間解耦提供了解決方案
    2021-06-06
  • SpringDataJpa如何使用union多表分頁條件查詢

    SpringDataJpa如何使用union多表分頁條件查詢

    這篇文章主要介紹了SpringDataJpa如何使用union多表分頁條件查詢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java的異常類型總結(jié)

    Java的異常類型總結(jié)

    在本篇文章里小編給大家分享了關(guān)于Java的異常類型的相關(guān)知識點(diǎn)內(nèi)容,有需要的朋友們跟著學(xué)習(xí)下。
    2019-01-01

最新評論