Day16基础不牢地动山摇-Java基础

目录
  • 1、反射机制
    • 1.1 认识反射
    • 1.2 取得父类信息
    • 1.3 反射调用构造
    • 1.4 反射调用方法
    • 1.5 反射调用成员
    • 1.6 反射与简单Java类—单级VO操作原理
    • 1.7 单极自动VO设置实现
    • 1.8 反射与简单Java类—多级VO设置实现
  • 2、ClassLoader类加载器
    • 2.1 认识类加载器
    • 2.2 自定义ClassLoader

1、反射机制

反射机制如果只是针对普通开发者而言意义不大,一般都是作为一些系统的构架设计去使用的,包括以后学习的开源框架,那么几乎都是反射机制。

1.1 认识反射

反射指的是对象的反向处理操作,就首先观察以下“正”的操作,在默认情况下,必须先导入一个包才能产生类的实例化对象。

所谓的“反”根据对象来取得对象的来源信息,“反”的操作的本来来源就是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());

	}
}

此时通过对象的确对象的来源,就是“反”的本质。在反射的背后不在是一个对象,而是对象身后的来源。

而这个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内部定义的一个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());//反着来
	}
}

在以上给出的三个方法会发现一个神奇的地方,除了第一种形式会产生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);
	}
}

现在可以发现,对于对象的实例化操作,除了使用关键字new之外又多了一个反射机制操作,而且这个操作要比之前使用的new复杂一些,可是有什么用呢?

对于程序的开发模式之前一直强点:尽量减少耦合,而减少耦合的最好的做法是使用接口,但是就算使用了接口也逃不出关键字new,多以实际上new是耦合的关键元凶。

1.2 取得父类信息

反射可以做出一个对象所具备的所有操作行为,而且最关键的是这一切的操作都可以基于Object类型进行。

在Java里面任何的程序类实际上都一定会有一个父类,在Class类里面就可以通过此类方式来取得父类或者是实现的父接口,有如下两个方法提供:

public 软件包 getPackage() 取得类的包名称
public 类<? super T> getSuperclass() 取得父类的Class对象
public 类<?>[] getInterfaces() 取得父接口

取得类的相关信息

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

通过我们反射可以取得类结构上的所有关键信息。

1.3 反射调用构造

一个类可以存在多个构造方法,如果我们要想取得类中构造的调用,我们就可以使用Class类提供的两个方法

public Constructor getConstructor(类<?>… parameterTypes)
throws NoSuchMethodException,
SecurityException
取得指定参数类型的构造方法
public Constructor<?>[] getConstructors()
throws SecurityException
取得类中的所有构造

以上两个方法的返回类型都是java.lang.reflect.Constructor类的实例化对象,这个类里面关注一个方法,实例化对象:public T newInstance(Object… initargs) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException

取得类中所有构造方法的信息—利用Constructor类中的toString()方法取得了构造方法的完整信息

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()方法就比较麻烦

自己拼凑构造方法操作

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

学习Constructor类目的并不是分析方法的组成,最需要的关注就是问题的结论:在定义简单的java类一定要保留一个无参构造。

观察没有无参构造的方法

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

此时运行的时候出现了错误提示“java.lang.InstancetiationException”因为以上的方式使用反射实例化对象时需要的是类之中提供无参构造方法,但是现在既然没有了无参构造方法,那么就必须明确的找到一个构造方法。

通过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对象
        //现在明确表示取得指定参数类型的构造方法对象
		Constructor<?> cont = cls.getConstructor(String.class,int.class);
		System.out.println(cont.newInstance("张三",19));

	}
}

一行写简单Java类要写无参构造,以上内容就只需要了解就可以了。

1.4 反射调用方法

当取得了一个类之中的实例化对象之后,下面最需要调用的肯定是类之中的方法,所以可以继续使用Class类取得一个类中所定义的方法定义:

**public Method[] getMethods()
throws SecurityException
取得全部方法
public Method getMethod(String name,Class<?>… parameterTypes)
throws NoSuchMethodException, SecurityException
取得指定方法

发现以上的方法返回的都是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类对象最大的作用不在于方法的列出(方法的列出都在开发工具上使用了),但是对于取得了Method类对象之后还有一个最大的功能,就是可以利用反射调用类的方法:
调用方法:public Object invoke(Object obj,Object… args) throws IllegalAccessException,IllegalArgumentException,InvocationTargetException
之前调用类中的方法的时候使用的都是“对象.方法”,但是现在有了反射之后,可以直接利用Object类调用指定子类的操作方法。(同事解释一下,为什么setter,和getter方法的命名要求如此严格)。

利用反射调用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);//通过反射构建方法
   	Method getM=cls.getMethod("getName");
   	setM.invoke(obj, "小张同学");//键值对的形式传递参数此过程相当于setM
   	Object result = getM.invoke(obj);
   	System.out.println(result);
   }
}

在日后所有的技术开发中,简单Java类都是如此应用,多以必须按照标准进行。

1.5 反射调用成员

个组成部分就是成员(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类之中提供了两个方法:

设置属性内容(类似于:对象.属性=内容):public void set(Object obj,Object value) throws IllegalArgumentException,IllegalAccessException
取得属性内容(类似于:对象.属性):public Object get(Object obj) throws IllegalArgumentException,IllegalAccessException

可是从类的开发要求而言,一直都强调类之中的属性必须封装,所以现在调用之前要想办法解除封装。

  • 解除封装(重点):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设置的属性是私有属性,所以是无法操作的
		field.setAccessible(true);///解决封装
		field.set(obj, "小张");
		System.out.println(field.get(obj));
	}
}

虽然反射机制运行直接操作类之中的属性,可是不会有任何一种程序直接操作属性,都会通过setter,getter方法。

1.6 反射与简单Java类—单级VO操作原理

如果现在又一个简单Java类,那么这个简单Java类中的属性按照原始的做法一定要通过setter才可以设置,取得肯定继续使用getter(不关注此处)。

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 ){//设置属性内容
		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设置实现

现在所有操作都是通过TestDemo类调用EmpAciton类实现的,而EmpAciton类的主要作用在于定位要操作属性的类型。同时该程序应该符合所有的简单Java类开发形式,也就意味着我们的设计必须有一个单独的类来实现。

由于Bean的处理操作肯定需要重复出去对象信息,所以我们还需要准备两个程序类:StringUtils,负责字符串的操作,毕竟属性的首字母需要大写处理,而后在写一个对象的具体操作(取得对象、设置对象内容)。

工具类—BeanOperation.java

package com.day16.util;

/**
 * @author 张晟睿
 *	本类主要负责实现自动VO匹配处理操作,本身不需要通过实例化对象完成,所以构造方法私有化
 */

public class BeanOperation {
	private BeanOperation(){}

	/**
	 * @param actionObject	表示当前发出设置请求的程序类的当前对象
	 * @param msg	所有属性的具体内容,格式“属性名称:内容|属性名称:内容”
	 *
	 */
	public static void setBeanValue(Object actionObject,String msg) throws Exception{
		String result [] = msg.split("\\|");
		for (int i = 0; i < result.length; i++) {
			//需要针对于给定的属性名称和内容进行一次拆分
			String temp[] = result[i].split(":");
			String attribute = temp[0];//属性名称,包括“XxxAction属性和具体的简单AJava类的属性”
			String value = temp[1];//接收具体的内容属性
			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 张晟睿
 *	本类的主要功能是根据属性名称调用响应类中getter、setter方法
 */
public class ObjectUtils {
	private ObjectUtils(){}
	/**
	 * 根据指定的类对象,设置类中的属性
	 * @param wrapo 属性所在类的实例化对象
	 * @param attribute	属性名称
	 * @param value	属性内容
	 */
	public static void setObjectValue(Object wrapo,String attribute, String value) throws Exception{

		//调用指定属性的Field对象,母的是取得对象类型,如果没有属性也就是说该操作无法继续
		Field field = wrapo.getClass().getDeclaredField(attribute);//判断属性是否存在
		if(field == null){
			field = wrapo.getClass().getField(attribute);
		}
		if(field == null){//两次操作都无法取得对应的成员变量
			return ;//该属性一定不存在
		}
		String methodName = "set" + StringUtils.initcap(attribute);
		Method method = wrapo.getClass().getMethod(methodName,field.getType());
		method.invoke(wrapo, value);
	}
	/**
	 * 负责调用指定类中getter方法
	 * @param wrapo 表示要调用方法的所在对象
	 * @param attribute	表示属性名称
	 * @return	调用对象的结果
	 */
	public static Object getObject(Object wrapo,String attribute) throws Exception{
		String methodName = "get" + StringUtils.initcap(attribute);//定义getter方法
		//调用指定属性的Field对象,母的是取得对象类型,如果没有属性也就是说该操作无法继续
		Field field = wrapo.getClass().getDeclaredField(attribute);
		if(field == null){
			field = wrapo.getClass().getField(attribute);
		}
		if(field == null){//两次操作都无法取得对应的成员变量
			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 ){//设置属性内容
		//之所以传递this,主要将EmpAction的类对象传递方法里面
		//因为给定的标记:emp.ename:smith,而emp应该对象的是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设置实现

现在假设一个雇员属于一个部门,一个部门属于一个公司,一个公司属于一个城市,一个城市属于一个省份,一个省份属于一个国家,这种类似关系都可以通过字符串实现多级配置。

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

此时所有的引用关系上都自动进行了对象实例化。而现在程序希望可以满足于单级和多级。

修改BeanOperation.java

package com.day16.util;

/**
 * @author 张晟睿
 *	本类主要负责实现自动VO匹配处理操作,本身不需要通过实例化对象完成,所以构造方法私有化
 */

public class BeanOperation {
	private BeanOperation(){}

	/**
	 * @param actionObject	表示当前发出设置请求的程序类的当前对象
	 * @param msg	所有属性的具体内容,格式“属性名称:内容|属性名称:内容”
	 *
	 */
	public static void setBeanValue(Object actionObject,String msg) throws Exception{
		String result [] = msg.split("\\|");
		for (int i = 0; i < result.length; i++) {
			//需要针对于给定的属性名称和内容进行一次拆分
			String temp[] = result[i].split(":");
			String attribute = temp[0];//属性名称,包括“XxxAction属性和具体的简单AJava类的属性”
			String value = temp[1];//接收具体的内容属性
			String fields [] = attribute.split("\\.");//拆分出属性信息
			if(fields.length > 2){//多级配置
				//如果要想多级确定出属性的操作对象,那么应该一层找出每一个getter方法返回的内容
				Object currentObject = actionObject;//确定当前要操作的对象
				for (int j = 0; j < fields.length - 1; j++) {//对应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:财务部|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配置的路径进行加载,而我们的类加载的路径可能是网络、文件、数据库。这是ClassLoader类主要作用。

2.1 认识类加载器

首先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
*/

出现两个加载器AppClassLoader(应用程序类加载器)、ExtClassLoader(扩展类加载器)。

对于第三方程序类库除了CLASSPATH之外,实际上在java里面还有一个加载目录:C:\ProgramFiles\Java\jdk1.8.0_241\jre\lib\ext

观察类我们发现ClassLoader里有一个方法:public 类<?> loadClass(String name) throws ClassNotFoundException,进行类的加载操作处理。

2.2 自定义ClassLoader

**实现文件的类加载器 **

package com.day17.demo;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

class MyClassLoader extends ClassLoader{
	/**
	 * 实现一个自定义的类加载器,传入类名称后,通过指定文件路径加载
	 * @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];//定义读取的缓冲区
		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());
	}
}

类加载器给我们用户最大的帮助就是在于可以通过动态的路径实现类的加载处理操作。

到此这篇关于Day16基础不牢地动山摇-Java基础的文章就介绍到这了,更多相关Java基础内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 一篇文章带你深入了解javaIO基础

    目录 一.认识IO 1.IO的分类 2.IO的方式 3.IO读写的方式 4.IO的特性 二.文件操作 1.文件的构成 2.文件的创建 3.文件操作的API使用 三.IO流 1.流的分类 2.流的创建 3.流的使用 <1>输入流 <2>输出流 <3>实例:文件的复制 总结 一.认识IO 1.IO的分类 (1)BIO:同步阻塞IO (2)NIO:同步非阻塞IO (3)AIO:异步阻塞IO 注意: 这里主要介绍BIO 2.IO的方式 IO本质就是对数据的操作 (1)网络IO

  • Java线程池详细解读

    目录 1.线程池 1.1 线程池概念 1.2 线程池的实现 2.StringBuffer类 面试题:请解释String.StringBuffer.StringBuilder的区别? 3.Runtime类 面试题:什么叫gc?如何处理 4.System类 面试题:请解释final.finally.finalize的区别? 5.对象克隆 6.Date类 6.1 日期处理类-Date类 6.2 日期格式化-SimpleDateFormat类(核心) 7. 数字操作类-Math类 7.1 随机数-Ran

  • Day10基础不牢地动山摇-Java基础

    目录 1.异常的捕获与处理 1.1 处理异常 1.2 异常处理的流程 1.3 throw关键字 1.4 异常处理模型 1.5 RuntimeException 1.6 断言:assert 1.7 自定义异常 2.链表 2.1 链表基本的结构 2.2 链表实现结构说明 2.3 增加链表数据-public void add(数据) 2.4 增加多个数据-public void addAll(数据数组) 2.5 统计数据个数-public int size() 2.6 链表数据转换为对象数组-publ

  • Java设计模式之代理模式详细解读

    目录 Java设计模式-代理模式 什么是代理模式? 代理模式-UML图: 源代码: 运行结果: 总结: 应用实例: 优点: 缺点: 使用场景: Java设计模式-代理模式 什么是代理模式? 在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 所谓的代理严格来讲就是两个子类共同实现一个接口,其中一个子类负责真实业务实现,另一个辅助完成主类业务逻辑操作. 代理模式-UML图: 源

  • Day14基础不牢地动山摇-Java基础

    目录 1.定时器 2.UUID类 3.Base64加密处理 加密处理 多次加密 4.ThreadLocal类 5.IO-File类 5.1 基本操作 5.2 取得文件信息 5.3 综合案例:目录列表 6.IO- 字节流与字符流 6.1 字节输出流:OutputStream 6.2 字节输入流:InputStream 6.3 字符输出流:Writer 6.4 字符输入流:Reader 6.5 字节流与字符流区别 7.转换流 1.定时器 推动整个计算机硬件的发展的核心关键性技术就是时钟.所以在企业开

  • Day15基础不牢地动山摇-Java基础

    目录 1.字符编码 1.1 常用字符编码 1.2 乱码产生分析 2.内存流基本操作 3.打印流 3.1 格式化文本信息 4. System类 4.1 系统输出 4.2 系统输出 4.3 系统输入 5.BufferedReader类 6.Scanner 7.对象序列化 7.1 对象序列化的概念 7.2 实现序列化和反序列化 7.3 transient关键字(了解) 1.字符编码 1.1 常用字符编码 在计算机的世界之中,所有的显示文字都是按照其指定的数字编码进行保存的,如果没有正确的解码,那么就坑

  • Day16基础不牢地动山摇-Java基础

    目录 1.反射机制 1.1 认识反射 1.2 取得父类信息 1.3 反射调用构造 1.4 反射调用方法 1.5 反射调用成员 1.6 反射与简单Java类-单级VO操作原理 1.7 单极自动VO设置实现 1.8 反射与简单Java类-多级VO设置实现 2.ClassLoader类加载器 2.1 认识类加载器 2.2 自定义ClassLoader 1.反射机制 反射机制如果只是针对普通开发者而言意义不大,一般都是作为一些系统的构架设计去使用的,包括以后学习的开源框架,那么几乎都是反射机制. 1.1

  • Day11基础不牢地动山摇-Java基础

    目录 1.Eclipse开发工具 1.1 Eclipse历史 1.2 快捷键 1.3 Debug调试 1.4 JUNIT测试工具 2.Java基础新特性 2.1 可变参数 2.2 foreach输出 2.3 静态导入 3. JDK三大主要特性--泛型 3.1 泛型的引出 3.2 泛型实现 3.3 通配符 3.4 泛型接口 3.5 泛型方法 4.JDK三大主要特性--枚举 4.1 多例与枚举 4.2 Enum类 面试题:请解释enum和Enum的区别? 4.3 枚举中定义其它结构 4.4 枚举应用

  • Day12基础不牢地动山摇-Java基础

    目录 1.多线程 1.1 多线程的基本概念 1.2 多线程的实现 1.3 继承Thread类实现多线程 1.4 Runnable接口实现多线程 1.5 Thread类和Runnable接口实现多线程的区别 1.6 线程的操作状态 1.7 Callable实现多线程 1.8 线程命名和取得 1.9 线程的休眠 1.10 线程的优先级 1.11 线程的同步与死锁 1.12 死锁 综合案例 1.解决数据错位问题:依靠同步解决 2.解决数据的重复设置和重复取出 面试题:请解释sleep()和wait()

  • 基础不牢,地动山摇,Java基础速来刷刷

    Java类结构以及main函数 类是Java中最基础的逻辑单位 java所有内容都是需要在类中的,内容不允许游离在类之外,简单说Java项目就是由一个个类组成 类的构成 成员变量/属性 成员方法/函数 注意:Java要求文件名和类名需要一致 main函数 这里的main函数特指psvm,主方法 一个class文件最多只能有一个main函数 一个类可以没有main函数,没有main函数的类就不能主动执行,但是可以被动(被调用执行) main函数是程序的入口,和C/C++一致,但是Java要求所有的

  • Java基础之匿名内部类、包装类

    目录 1.匿名内部类 2.Object类简介 2.1 取得对象信息toString() 2.2 对象的比较equals() 2.3 Object接口引用数据类型 3.包装类 3.1 装箱与拆箱 3.2 字符串与基本数据类型的转换 3.3 包的定义 3.4 包的导入 4.访问控制权限 5.jar命令 1.匿名内部类 内部类:在一个类的内部定义了另外的类,称为内部类,匿名内部类指的是没有名字的内部类.为了清楚内部类的主要作用,下面首先观察一个代码. interface IMessage{ publi

  • Java基础字符编码与内存流详细解读

    目录 1.字符编码 1.1 常用字符编码 1.2 乱码产生分析 2.内存流基本操作 3.打印流 3.1 格式化文本信息 4. System类 4.1 系统输出 4.2 系统输出 4.3 系统输入 5.BufferedReader类 6.Scanner 7.对象序列化 7.1 对象序列化的概念 7.2 实现序列化和反序列化 7.3 transient关键字(了解) 1.字符编码 1.1 常用字符编码 在计算机的世界之中,所有的显示文字都是按照其指定的数字编码进行保存的,如果没有正确的解码,那么就坑

  • Java基础知识汇总

    Java基础知识 1.Java语言的优点: 1)Java是纯面向对象语言 2)与平台无关性,一次编译到处运行 3)Java提供了狠多内置类库 4)提供了对web应用的支持 5)具有较好的安全性(数组边界检测.Bytecode检测)和健壮性(强制型机制.垃圾回收器.异常处理) 6)去除c++难以理解的一些特性(头文件 指针 运算符重载 多重继承) 2.java与c++的异同: 1)Java为解释型语言,c++为编译型语言,java会慢但是跨平台 2)Jave为纯面向对象,c++既面向对象又能面向过

随机推荐