[Java]阶段性知识点、技术总结

1.自动装箱、拆箱:

自动装箱:指开发人员可以把一个基本数据类型直接赋给对应的包装类。

自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型。

举例:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 自动装箱拆箱------>封装对象
		// 1.5 jvm
		// Integer i=1;//装箱
		// int j=i;//拆箱

		List list = new ArrayList();// 无泛型,则为Object对象,需要强制转换
		list.add(1);// 自动装箱,此前要用list.add(Integer(1))
		list.add(2);
		list.add(3);

		Iterator it = list.iterator();
		while (it.hasNext()) {
			int k = (Integer) it.next();// 拆箱
		}
	}

2.增强for循环:

增强for循环只能用在数组、或实现Iterable接口的集合类上。

举例:

public void test2() {
		List list = new ArrayList();
		list.add(1);
		list.add(2);
		list.add(3);

		// 不能改变值,obj指向另一个值而已,没改变list的原值
		// 想改变只能用传统方式
		for (Object obj : list) {
			int i = (Integer) obj;// 没有泛型只能强转
			System.out.println(i);
			obj = 10;// obj指向了另外的数据,而不是改变了list里的值!
		}
	}

3.可变参数

调用可变参数的方法时, 编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数

可变参数只能处于参数列表的最后, 所以一个方法最多只能有一个长度可变的参数

可变参数就看成是数组。

举例:

public static void sum(int ... nums){
		//可变参数在用时,当成数组即可
		int sum = 0;
		for(int num : nums){
			sum += num;
		}
		System.out.println(sum);
	}

Arrays.asList(T...a)方法:传入多个对象或多个对-象-数-组都可以---->注意如果传入基本类型数组,将把整个数组当作一个对象处理!

举例:

List list = Arrays.asList("aa","bb","cc");
		System.out.println(list);

		String[] str = {"xx","yy","zz"};
		list = Arrays.asList(str);
		System.out.println(list);

传入基本数据类型的情况:

//注意以下代码int数组和Integer数组的不同
		int arr[] = {1,2,3};
		list = Arrays.asList(arr);
		System.out.println(list);

(注意这里不能打印[1,2,3])

4.枚举类

?枚举类也是一种特殊形式的Java类。

?枚举类中声明的每一个枚举值代表枚举类的一个实例对象。

?与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。

带抽象方法的枚举:每个内部枚举对象以内部类的方式实现该枚举类

// 带抽象方法的枚举:调用该方法时,返回中国的成绩等级
enum Grade {// 也是一个类
	// 为每个可能值(对象)初始化分数,传给其value字段
	A("100-90") {// 因为类存在抽象方法,所以在初始化时要实现其抽象方法
		public String localeValue() {// 那么调用A的该方法返回"优",这其实是一个匿名内部类(子类)了
			return "优";
		}//就把ABCDE看成是恰恰在本类内部初始化的对象吧!
	},
	B("89-80") {
		public String localeValue() {
			return "良";
		}
	},
	C("79-70") {
		public String localeValue() {
			return "一般";
		}
	},
	D("69-60") {
		public String localeValue() {
			return "差";
		}
	},
	E("59-0") {
		public String localeValue() {
			return "不及格";
		}
	};

	private String value;// 封装每个对象对应的分数

	// 注意是私有构造函数,外人不可以初始化!
	private Grade(String value) {
		this.value = value;
	}

	public String getValue() {// 调用枚举对象的value字段获取自定义分数值
		return this.value;
	}

	public abstract String localeValue();
}
@Test
	public void test() {
		print(Grade.B);// 调用枚举类型的B类成绩(不能用Grade g=B的方式初始化,构造函数私有)
	}

	public void print(Grade g) {// ABCDE
		String value = g.getValue();// 调用其方法
		String value1 = g.localeValue();// 调用其方法
		System.out.println(value);
		System.out.println(value1);
	}

5.加载类与反射

Java中有一个Class类用于代表某一个类的字节码。

Class类即然代表某个类的字节码,它当然就要提供加载某个类字节码的方法:forName()。forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

另外两种得到class对象的方式

类名.class

对象.getClass()

public static void main(String[] args) throws ClassNotFoundException {
		// TODO Auto-generated method stub
		// 用Class类来加载一个完整名称的类(带完整包名)
		Class clazz = Class.forName("cn.itcast.reflect.Person");// 保存加载的类的字节码

		// 第二种获取字节码的方式
		Class clazz1 = new Person().getClass();// new对象也加载类,再通过其方法获取类字节码

		// 第三种
		Class clazz2 = Person.class;
	}

	// 解剖类的构造函数,创建类的对象
	@Test
	public void test1() throws ClassNotFoundException,
			IllegalArgumentException, InstantiationException,
			IllegalAccessException, InvocationTargetException,
			SecurityException, NoSuchMethodException {

		Class clazz = Class.forName("cn.itcast.reflect.Person");// 类的字节码加载进内存

		Constructor c = clazz.getConstructor(null);// 解剖出无参构造函数

		Person p = (Person) c.newInstance(null);// 解剖出的构造函数类一定有这个创建对象的方法(调用对应构造函数),返回Object对象,要强转

		System.out.println(p.name);

		// 要在框架里应用,框架里加载类是用配置文件,里面的类名是一个字符串,想加载配置文件里的类名来自动调用类,而你是无法用一个
		// 类名字符串来new对象的
		// 自动调用,加载类是用配置文件,所以你也无法确知类名,用手动的方式创建对象
		// 我们不用做框架,但要知道框架原理,使用框架
		// 配置文件一配,框架自动帮我创建出对象,并可以调用各种属性和方法,就是因为框架后台有这样一段代码

	}
@Test
	public void test2() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Constructor c = clazz.getConstructor(String.class);// 参数列表是Class对象的一个数组,标识构造函数形参类型,它是Class的实例
		Person p = (Person) c.newInstance("dsfsda");
	}

	@Test
	public void test3() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Constructor c = clazz.getConstructor(String.class, int.class);// 参数列表是Class对象的一个数组,标识构造函数形参类型

		Person p = (Person) c.newInstance("fsfs", 12);
		System.out.println(p.name);
	}
@Test
	public void test4() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Constructor c = clazz.getDeclaredConstructor(List.class);// private类型的构造函数,而getConstructor只能得到public类型
		c.setAccessible(true);// <strong>报错,私有的方法不能在外部访问,用暴力反射,强制可以访问</strong>
		Person p = (Person) c.newInstance(new ArrayList());// 传参
	}

	// 创建对象的另外一种途径:等效于test1
	@Test
	public void test5() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");// 获取类的字节码
		Person p = (Person) clazz.newInstance();// 其实这个方法内部也是封装<strong>调用了这个类的无-参-构造函数,</strong>所以必须保证定义了无参构造函数
		System.out.println(p);
	}

解析、执行方法:

//Class加载类字节码;Method加载方法字节码(包括参数类型字节码),执行方法,执行某个具体对象的方法
public class Demo3 {
	@Test
	public void test1() throws ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, SecurityException, NoSuchMethodException {
		// 反射类的方法
		Person p = new Person();
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method1 = clazz.getMethod("aa1", null);// 调用无参的方法
		method1.invoke(p, null);// 调用方法,要传一个具体对象进去
	}

	@Test
	public void test2() throws ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, SecurityException, NoSuchMethodException {
		Person p = new Person();

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("aa1", String.class, int.class);// 方法名,参数类型(.class文件,因为参数必须要传入对象实体才行!)
		method.invoke(p, "zfdsl", 38);// 调用某个对象的方法,并传入参数
	}

	@Test
	public void test3() throws ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, SecurityException, NoSuchMethodException {
		Person p = new Person();
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("aa1", String.class, int[].class);
		// 注意这个调用是有返回值的,但需要强转
		Class cs[] = (Class[]) method.invoke(p, "aaaa", new int[] { 1, 23 });
		System.out.println(cs[0]);
	}

	@Test
	public void test4() throws Exception {
		Person p = new Person();
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getDeclaredMethod("aa1", InputStream.class);
		// 私有方法是可以获取的,但是要想用对象调用,必须先暴力反射
		method.setAccessible(true);
		method.invoke(p, new FileInputStream("c:\\rt.txt"));// 不能给空参数,否则会认为是调用无参的那个aa1方法,报错
	}// 出现什么multiple markers的错误:一是没有导包,二是没抛各种异常,三是创建数组格式错误(大括号包元素!)!!!

	@Test
	public void test5() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");

		Method method = clazz.getMethod("aa1", int.class);
		// 静态方法不需要对象!传入null!
		method.invoke(null, 23);
	}

	// 反射main方法
	// 传参时jdk1.5接收可变参数,jdk1.4只接收数组,为了与1.4兼容,1.5也接收数组,方法的原理是拆数组成多个参数(注意如果是多个参数的方法写成可变参数形式不会出问题,1.5会调用可变参数形式而1.4会报错)
	// 而main方法的参数恰好是一个数组,那么1.5,1.4都采用拆开数组的方式变成多个参数,这样就导致main方法传参错误
	// 所以,要把main方法的数组参数再包进一个数组里,这样拆数组就拆出唯一一个数组参数,调用正确!
	@Test
	// 不仅是main,还要小心所有接收数组参数的方法!!!
	public void test6() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("main", String[].class);
		method.invoke(null, new Object[] { new String[] { "aa", "bb" } });// 静态方法不需要传对象!
		// 另一种办法:强转,欺骗,不让它解析成数组!
		method.invoke(null, (Object) new String[] { "aa", "bb" });
	}
}

反射字段:反射出后,想获取某个对象字段的值,需要强转,如果无法确知类型,调用Field类对象的getType方法

@Test
	public void test1() throws Exception {
		Person p = new Person();

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Field f = clazz.getField("name");
		// String name = (String) f.get(p);// 强转,并且要有对象
		// System.out.println(name);

		// 获取字段的值
		Object value = f.get(p);

		// 返回字段类型
		Class type = f.getType();
		System.out.println(type);

		// 判断后再强转
		if (type.equals(String.class)) {
			String svalue = (String) value;
			System.out.println(svalue);
		}

	}

	@Test
	public void test2() throws Exception {
		Person p = new Person();
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Field f = clazz.getDeclaredField("password");
		f.setAccessible(true);// 私有的要暴力反射
		System.out.println(f.get(p));
	}

6.JavaBean属性的意义与内省操作

一个JavaBean:

public class Person {// javabean----------->封装用户数据
	private String name;
	private String password;// 字段--------->只有提供了set或get方法才称作属性
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getAb() {// -----------><strong>这也是属性</strong>--------><strong>这个javabean一共有5个属性,因为Object类中还有一个getClass方法!</strong>
		return null;
	}
}

内省操作:

//使用内省aip操作bean的属性
public class Demo1 {
	@Test
	public void test1() throws Exception {
		BeanInfo info = Introspector.getBeanInfo(Person.class, Object.class);// 内省其属性,去掉Object的属性
		PropertyDescriptor[] pds = info.getPropertyDescriptors();// 属性描述器
		for (PropertyDescriptor pd : pds) {
			System.out.println(pd.getName());
		}
	}

	@Test
	// 操作bean的指定属性
	public void test2() throws Exception {
		Person p = new Person();

		PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
		// 获取属性的写方法
		Method method = pd.getWriteMethod();
		// 执行此方法
		method.invoke(p, 88);

		Method method1 = pd.getReadMethod();

		int a = (Integer) method1.invoke(p, null);// 有返回值,Object对象,强转

		System.out.println(a);
	}

	// 获取当前操作属性的类型
	@Test
	public void test3() throws Exception {
		Person p = new Person();

		PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);

		Class c = pd.getPropertyType();// 类型,Class对象

		System.out.println(c);
	}
}

7.Dom解析

xml文档:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE 书架 SYSTEM "book.dtd">
<书架>
	<书>
		<书名 name="中科大">javaweb开发</书名>
		<作者>张孝祥</作者>
		<售价>99.00元</售价>
		<售价>109.00元</售价>
   <售价>89.00元</售价></书>
	<书>
		<书名>JavaScript网页开发</书名>
		<作者>张孝祥</作者>
		<售价>28.00元</售价>
	</书>
	<页面作者 个人爱好="上网" 网站职务="页面作者" 联系信息="aaaa"/><!--实际三个属性,还有一个固定属性和一个默认属性-->
</书架>

附DTD约束(文档,同一目录下):

<pre name="code" class="html"><!ENTITY bookname "javaweb开发">

<!ELEMENT 书架 (书+,页面作者*)>
<!ELEMENT 书 (书名,作者,售价+)>
<!ELEMENT 书名 (#PCDATA)>
<!ELEMENT 作者 (#PCDATA)>
<!ELEMENT 售价 (#PCDATA)>
<!ATTLIST 书名 name CDATA #IMPLIED>
<!ATTLIST 页面作者
姓名 CDATA #IMPLIED
年龄 CDATA #IMPLIED
联系信息 CDATA #REQUIRED
网站职务 CDATA #FIXED "页面作者"
个人爱好 CDATA "上网"
>

DOM解析:输出所有节点名(递归)

@Test
	public void read() throws ParserConfigurationException, SAXException, IOException{
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=factory.newDocumentBuilder();
		Document document=builder.parse("src/book.xml");

		//得到根节点------->都是Node类型
		//注意不要导错包!技巧是导错了一定伴随强转,导了包还需要强转就是导错包了!
		Node root=document.getElementsByTagName("书架").item(0);

		//调用递归方法,遍历、打印所有子孙节点名称
		list(root);
	}

	private void list(Node node){
		//先打印此节点名称
		System.out.println(node.getNodeName());
		NodeList list=node.getChildNodes();
		for(int i=0;i<list.getLength();i++){
			Node child=list.item(i);
			//以子节点为参数调用自身
			list(child);
		}
	}

结果:

书架

#text

#text

书名

#text

#text

作者

#text

#text

售价

#text

#text

售价

#text

#text

售价

#text

#text

#text

书名

#text

#text

作者

#text

#text

售价

#text

#text

#text

页面作者

#comment

#text

注意:这里不同行之间的空格和换行也被当作了text节点对象!!由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。

如果只想打印所有标签,则加上判断:

private void list(Node node){
		//先打印此节点名称
		if(node instanceof Element){
			System.out.println(node.getNodeName());
		}
		NodeList list=node.getChildNodes();
		for(int i=0;i<list.getLength();i++){
			Node child=list.item(i);
			//以子节点为参数调用自身
			list(child);
		}
	}

结果:

书架

书名

作者

售价

售价

售价

书名

作者

售价

页面作者

解析标签属性:用Element对象

@Test
	public void read1() throws ParserConfigurationException, SAXException, IOException{
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=factory.newDocumentBuilder();
		Document document=builder.parse("src/book.xml");

		//知道它是标签,才强转成标签
		Element bookname=(Element)document.getElementsByTagName("书名").item(0);
		String value=bookname.getAttribute("name");
		System.out.println(value);
	}

结果:

中科大

添加节点:要把Document对象重写写入xml文档

Transformer类和DocumentBuilder一样,构造方法都是被保护的,需要通过工厂类实例化对象。

例子:

@Test
	public void add() throws ParserConfigurationException, SAXException, IOException, TransformerException{
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=factory.newDocumentBuilder();
		Document document=builder.parse("src/book.xml");

		//创建节点
		Element price=document.createElement("售价");
		price.setTextContent("59.00元");
		//挂到第一本书
		Element book=(Element)document.getElementsByTagName("书").item(0);
		book.appendChild(price);

		//把更新后的内存数据写回xml文档
		TransformerFactory tffactory=TransformerFactory.newInstance();
		Transformer tf=tffactory.newTransformer();
		tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
	}
@Test
	//向指定位置插入
	public void add2() throws ParserConfigurationException, SAXException, IOException, TransformerException{
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=factory.newDocumentBuilder();
		Document document=builder.parse("src/book.xml");

		//创建节点
		Element price=document.createElement("售价");
		price.setTextContent("1009.00元");

		//得到参考节点
		Element refNode=(Element)document.getElementsByTagName("售价").item(0);

		//得到要挂崽的节点
		Element book=(Element)document.getElementsByTagName("书").item(0);
		//向指定位置插入
		book.insertBefore(price, refNode);

		//把更新后的内存数据写回xml文档
		TransformerFactory tffactory=TransformerFactory.newInstance();
		Transformer tf=tffactory.newTransformer();
		tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
	}

删除售价节点所在的书节点:

@Test
	//删除节点
	public void delete() throws ParserConfigurationException, SAXException, IOException, TransformerException{
		DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
		DocumentBuilder builder=factory.newDocumentBuilder();
		Document document=builder.parse("src/book.xml");

		//得到要删除的节点
		Element e=(Element)document.getElementsByTagName("售价").item(0);

		//得到爷爷删除爸爸
		//以此类推,如果上溯到document节点则可以将整个文档内容删除(已测试过)
		e.getParentNode().getParentNode().removeChild(e.getParentNode());

		//把更新后的内存数据写回xml文档
		TransformerFactory tffactory=TransformerFactory.newInstance();
		Transformer tf=tffactory.newTransformer();
		tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
	}

得到、更新内容,属性(类推,从略):getTextContent,setTextContent,getAttribute,setAttribute---------->分别是Node和Element的方法

xfd

时间: 2024-11-09 00:02:09

[Java]阶段性知识点、技术总结的相关文章

java 面试知识点

关于基础知识:你可以看看这些名词或知识点,看是否能说出个一二三四来. JavaSE----基本语法.数据类型.操作符等:int.long.Integer.Long.if.else.for.while----面向对象:class(类).Object(对象).instance(实例).state(状态).behavior(行为).field.method.new.可见性(访问控制).attribute.property.package.import.static variable.class var

Java琐碎知识点

知识点1: 1 String str1 = "abc";// 没有创建任何对象 2 String str2 = new String("abc");// 创建了2个对象 3 String str3 = new String("abc");// 创建了1个对象 4 System.out.println(str1 == str2);// 输出:false 5 System.out.println(str1 == str3);// 输出:false 6

分布式服务架构之java远程调用技术浅析

分布式服务架构之java远程调用技术浅析     在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI.MINA.ESB.Burlap.Hessian.SOAP.EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基于什么原理实现的呢,了解这些是实现分布式服务框架的基础知识,而如果在性能上有高的要求的话,那深入了解这些技术背后的机制就是必须的了,在这篇blog中我们将来一探究竟,抛砖引玉,欢迎大家提供更多的实现远程通讯

Java 面试知识点解析(二)——高并发编程篇

前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大部分内容参照自这一篇文章,有一些自己补充的,也算是重新学习一下 Java 吧. 前序文章链接: Java 面试知识点解析(一)--基础知识篇 (一)高并发编程基础知识 这里涉及到一些基础的概念,我重新捧起了一下<实战 Java 高并发程序设计>这一本书,感觉到心潮澎湃,这或许就是笔者叙述功底扎实的

关于Java面试知识点解析——JVM基础篇

跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看到同事一个个都走了,自己也盲目的开始面试起来(期间也没有准备充分),到底是因为技术原因(影响自己的发展,偏移自己规划的轨迹),还是钱给少了,不受重视. 准备不充分的面试,完全是浪费时间,更是对自己的不负责(如果title很高,当我没说).今天给大家分享下 Java面试知识点解析--JVM基础篇 1)Java 是如何实现跨平台的? 注意:跨平台的是 Java 程序,而不是 JVM.JVM 是用 C/C++ 开发的,是

这些喜闻乐见的Java面试知识点,你都掌握了吗?

最近分享了一些有关学习方法和经验的文章,得到了很多读者的反馈,恰巧大家在昨天推文中的投票里一直选择了"Java基础的复习方法"这一项,那么今天我们就谈谈这方面的内容吧. 其实对于Java基础的学习,我觉得最好的方法就是理论结合实践,先通过书籍,博客等内容理解基本原理,再通过写一些demo进行实践,做到知其然又知其所以然. 前言 以下内容出自我的CSDN技术博客专栏,由于内容较多,我在这里只贴一个大概的目录. 本系列文章是我在秋招复习过程中创作和整理的内容,当时的初衷也是希望能够通过写博

Java 分布式处理技术

1.1 RMI 的基本概念 1.1.1 什么是RMI RMI(Remote Method Invocation) 远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一种机制,使用这种机制,某一台计算机上的对象在调用另外一台计算机上的方法时,使用的程序语法规则和在本地机上对象间的方法调用的语法规则一样. 1.1.2 RMI 的用途 1. 分布式体系结构 我们为什么要使用分布式计算呢? Ø         当我们想与多个用户或客户机共享一个中央资源(如一个数据库)时,就会使用分布式计算

序列化之Java默认序列化技术(ObjectOutputStream与ObjectInputStream)

Java默认序列化技术 主要是通过 对象输出流java.io.ObjectOutputStream 对象输入流java.io.ObjectInputStream 来实现的 package com.xingej.ser; public interface ISerializer { // 序列化,将obj序列化成字节数组 public <T> byte[] serialize(T obj); // 反序列化,将字节数组,反序列化为T public <T> T deserialize(

java编解码技术,netty nio

对于java提供的对象输入输出流ObjectInputStream与ObjectOutputStream,可以直接把java对象作为可存储的字节数组写入文件,也可以传输到网络上去.对与java开放人员来说,默认的jdk序列化机制可以避免操作底层的字节数组,从而提升开发效率. 1.为什么需要序列化 网络传输与对象序列化 2.java编解码技术指的什么 netty nio是基于网络传输,当进行远程跨进程服务调用时,需要把被传输的对象编码为字节数组或者bytebuffer对象.而当远程服务读取到byt