JavaSE整理
这是我在学习JavaSE时的知识点总结,某些部分可能不是很完善,您可以留下宝贵的建议,我会以最快速度修改。
-
基础语法
-
进制、进制分类、进制转换
0 开头为八进制
0b 开头为二进制
0x 开头为十六进制
-
原码、反码、补码
原码:一个字节8位,第一位用0/1表示正负
反码:负数的反码符号位不变,其余位按位取反
补码:负数的补码为反码+1(原码符号位后按位取反至最后一个1后照抄)
补码求原:负数-1取反
补码用于计算,计算后仍然是补码
-
数据类型、标识符
-
基本数据类型(值类型)
整形: byte(1byte), int(4byte), sort(2byte), long(8byte)
数据范围:[-2^(位数-1) , 2^(位数 -1) -1 ]
浮点型:float(4byte), double(8byte)float类型使用时需要在数据末端加f
布尔型:boolean
字符型:char ASCII码中 A-65 a-97 0-48
-
引用数据类型
String
-
标识符
命名规则:字母、数字、下划线、$;不能以数字开头;
不能是系统关键字或保留字
命名规范:望文知意;大驼峰、小驼峰
-
-
变量、常量
-
数据类型转换
自动类型转换/强制类型转换
数字->字符串:String valueOf();
字符串->数字:Integer parseInt();
字符串->数组:toCharArray();
数组->字符串:String valueOf();
-
运算符
算术运算符:
逻辑运算符:
关系运算符:
位运算符:
三目运算符:
-
-
流程控制
- 分支结构 if( condition ) { } else if( condition ) { } else{ body }
- 循环结构 while ( condition ){ }; do{ }while( condition ); for( ; ; ){ body }
-
方法
-
定义:一段代码或一个功能的抽取;方法体内的代码只有在调用时才会执行;
-
参数:声明时不能赋予初始值;
实参和形参;
动态参数:int… array 在方法中array是一个数组;动态参数需要写在形参的最后
-
返回值:返回值类型在方法名前定义;void代表没有返回值;return语句后跟返回值
-
方法的重载:
- 在同一个类中的方法;
- 方法的名相同
- 方法的参数类型或数量或顺序不同
-
方法的递归:方法的循环调用
-
-
数组
-
定义:用来存储相同类型数据的容器
-
特点:固定长度,即容量为固定值;容量在实例化时确定,之后不能更改
-
数组的声明与实例化
int[] arr = new int[5]; int[] arr = new int[]{1,2,3,4,5}; int[] arr = {1,2,3,4,5};
-
访问数组中的元素:通过数组元素的下标进行访问;下标从0开始
-
遍历数组元素:
//方法1 for(int i = 0 ; i < arr.length ; i ++){ System.out.println(arr[i]); } //方法2 for(a : arr){ System.out.println(a); }
-
数组排序:
//冒泡排序 for(int i = 0 ; i < arr.length - 1 ; i++) { for(int j = i + 1 ; j < arr.length ; j ++) { if(arr[i] < arr[j]){ int x = arr[i]; arr[i] = arr[j]; arr[j] = x; } } } //选择排序 int n; int value; for(int i = 0; i < arr.length - 1 ;i ++){ n = i; for(int j = i + 1 ; j < arr.length ; j ++) { if(value < arr[j]){ n = j; } } if(n != i){ value = arr[i]; arr[n] = value; arr[i] = arr[n]; } }
-
查找数组中的元素
- 顺序查找
- 二分查找(折半查找)数组需为有序数组
-
Array常用的工具类 java.util.Arrays
方法名 解释 Arrays.sort(array) 对指定的数组排序 Arrays.sort(array,fromIndex,endIndex) 对数组的指定下标范围进行排序 Arrays.binarySearch(array,value) 二分查找法,升序 Arrays.fill(arrar,value) 对数组元素赋予初始值 Arrays.fill(array,fromIndex,endIndex,value) 对数组指定区域元素赋予初始值 Arrays.copyOf(array,length) 指定长度的拷贝(深拷贝) -
Scanner类的使用 java.util.Scanner
Scanner scan = new Scanner(System.in); String str = scan.nextLine(); scan.close();
-
-
格式化字符串
String format();
符号 意义 %d 整型 %s 字符串类型 %f 浮点型 %02d 2位整数,不够补0 %.2f 保留小数点以后2位
面向对象
-
类
- 定义:是一种自定义的类型
- 类是一种引用类型
- 同一个包里不能有同名类
- 主函数可以定义在任何一个包里
- 一个文件中只能定义一个主函数
- 包package:对一个程序中部分代码的包装
-
static关键字
-
表示静态,可以用来修饰属性和方法
-
static修饰的部分,称为静态成员(类成员)、静态属性(类属性)、静态方法(类方法)
-
未被static修饰的部分称为非静态成员(实例成员)、非静态属性(实例属性、成员变量)、
实例方法(非静态方法、成员方法)
-
类的属性:
- 实例属性:实例化对象时在堆上开辟的空间存储
- 静态属性:这个类第一次被加载时在常量池开辟的属性
-
静态成员可以通过类名.成员名访问,非静态成员必须通过对象名.成员名来访问
-
静态成员的注意点
- 只能调用其他的静态方法
- 只能访问静态属性
- 不能以任何方式引用this或者super
-
-
this关键字
- this代表对当前对象的引用
- this关键字在非静态方法中使用
- this即调用该方法的对象
-
代码段
- 非静态代码段:执行顺序正常
- 静态代码段:static{ body; }在类第一次被加载时执行
-
构造方法
- 构造方法无返回值
- 方法名与类名相同
- 不能使用static修饰
- 实例化对象的时候会调用
- 系统默认提供的无参构造方法权限是public
-
封装性
private:私有化,修饰属性和方法;可以将属性私有化,避免外界直接访问
-
单例设计模式
-
饿汉式
class User{ private String name; private int age; private void User(String name,int age){ this.name = name; this.age = age; } private static User u = new User(name,age); public static User getUser(){ return u; } }
-
懒汉式
class User{ private void User(){ } private User u; public static User getUser(){ if(u == null) u = new User(); return u; } }
-
-
继承extends
-
父类(基类、超类)多个类中共同的属性被提取出来的父类
-
子类(派生类)具有相同特征的类,即为父类的子类
-
关键字extends 使用方法 class Dog extends Animal{ }
- java语言是单继承的语言,一个类只能有一个父类,一个类可以有多个子类
- Java中所有的类都直接或者间接的继承于Object类
- 子类可访问父类中可见的成员(访问权限问题)
- 有参构造方法不能被继承,可以通过super()进行调用
-
使用继承的原因
降低代码冗余度
若某一个类提供的功能不能满足需求且不可改动,可使用子类对功能进行拓展
-
继承中的构造方法
- 一个对象在实力化时,优先实例化父类部分
- 实例化父类部分时,默认使用父类中的无参构造
- 如果父类的无参构造不能访问?(给父类加无参构造/在子类构造方法中调用父类的构造方法)
- 关键字super表示对父类的引用
-
-
访问权限
用来描述一个类、方法、属性、接口、枚举。。。能访问到的范围
关键字 作用范围 适用范围 能访问的位置 public 公开 类成员、类 项目的任意位置 private 私有 类成员 当前的类(子类不允) protected 受保护 类成员 当前的包和跨包的子类 default / package 默认 类成员、类 当前的包 -
重写 @Override
- 又称覆写,指对同样的方法,用子类的实现覆盖掉父类的方法
- 子类的方法访问权限需要大于父类方法的访问权限(public>protected>default>private)
- 方法名和参数必须相同,返回值相同或父类方法的返回值的子类型
- 如果方法内存在异常,子类的异常需要等于父类的异常类型或者为父类的异常的子类型
-
final关键字
被修饰的 修饰后效果 变量 常量 类 最终类无法被继承 方法 最终方法无法重写 -
Object类
-
所有的类的父类
-
常用的方法
方法 说明 String toString() 返回的对象的字符串表示形式 Class<?> getClass() 获取一个对象类型 boolean equals() 比较对象是否相同 int hashCode() 获取一个对象的哈希码,散列码
(散列序列有 HashMap、HashSet)void finalize()throws Throwable{} 析构方法,在对象被实例化时和销毁前调用
-
-
多态
- 父类的引用可以指向了子类的对象,接口的引用可以指向实现类的对象
- 向上转型:
- 由子类转父类或者由实现类转为接口类型
- 一定会成功,属于隐式转换
- 向上转型后,将只能访问父类或者接口中的成员,对于重写了父类中的方法,将调用重写后的方法
- 向下转型
- 由父类转子类或由接口类型转为实现类类型
- 可能会失败,需要加显式转换
- 向下转型后可访问子类或实现类成员
- 向下转向前一般要进行判断,使用instanceof关键字
-
单列集合collection
-
collection接口中定义的常用的方法
方法名 说明 boolean add(Object o) 向集合中添加一个元素 boolean addAll(Collection c) 向集合中添加指定集合中的元素 void clear() 删除集合中的元素 boolean remove(Object o) 删除指定的元素 boolean removeAll(Collection c) 删除指定集合中的元素 boolean isEmpty() 判断集合是否为空 boolean contains(Object o) 判断集合是否包含指定元素 boolean containsAll(Collection c) 判断集合是否包含指定集合中的所有元素 Iterator iterator() 返回该集合的一个迭代器 int size() 获取该集合元素个数 以上方法可以在List与Set中使用
-
List
List接口继承了Collection中的所有方法,增加了一些根据元素索引操作集合的特有方法
方法 说明 void add(int index,Object o) 向集合的指定位置添加元素 boolean addAll(int index,Collection c) 向集合的指定位置添加指定集合中的元素 Object get(int index) 返回指定位的元素 Object remove(int index) 删除并返回指定位的元素 Object set(int index,Object o) 将指定位元素设置为o,并将替换后的元素返回 int inedxOf(Object o) 返回o在集合中第一次出现的下标 int lastIndexOf(Object o) 返回o在集合中最后一次出现的下标 List sub(int fromIndex,int toIndex) 返回一个指定起点与终点的子集合 -
ArrayList
- ArrayList里的大部分方法都是继承的
- 在ArrayList内部封装了一个长度可变的数组
- 使用这种集合类型有助于加快查询检索元素时的速度
- ArrayList与Vector相似,但ArrayList是线程不安全的
-
LinkedList
-
这个集合内部维护了一个双向循环链表
-
这种集合可以提高增删元素的效率
-
LinkedList里定义了一些自有的方法
方法 说明 void add(int index,E ele) 在列表的指定位插入元素 void addFirst(Object o) 在列表头插入元素 void addLast(Object o) 在列表尾插入元素 Object getFirst() 获取列表头的元素 Object getLast() 获取列表尾部的元素 Object removeFirst() 移除并返回列表头的元素 Object removeLast() 移除并返回列表尾的元素
-
-
Iterator和foreach
-
Iterator接口适用于遍历集合中的元素,Iterator对象也被称为迭代器
-
foreach循环也称增强for循环,只能用于遍历数组与集合中的元素,不能对其元素进行操作
-
ListIterator接口
方法 说明 void add(Object o) 将元素插入列表 boolean hasPrevious() 逆向遍历列表时使用 Object previous() 获取上一个元素 void remove() 从列表中移除由next或previous返回的最后一个元素 以上方法为ListIterator专有
-
-
Vector
- 用法与ArrayList类似,区别在于Vector是线程安全的
-
-
Set
Set接口中的方法与Collection中的方法基本一致,与List区别在与Set集合中的元素是无序且唯一的
Set集合中元素的存取与List集合中元素的存取方法一致
-
HashSet
- HashSet根据对象的哈希值来确定元素在集合中存储的位置,因此具有良好的存取和查找能力
- 向HashSet集合中添加一个对象时,首先会调用hashCode()方法来确定元素存储的位置,然后再调用equals()方法来确定该位置没有重复元素
-
TreeSet
-
TreeSet是根据二叉树的方式来存储元素,它可以实现对集合中的元素进行排序
-
向TreeSet集合中添加的元素类型需要实现Conparable接口中的CampareTo方法
-
在使用TreeSet添加元素时,系统会调用Comparable接口中的CompareTo方法
//方法一:在元素类内部实现compareTo()方法 public class Program{ public static void main(String[] args){ TreeSet ts = new TreeSet(); ts.add(new Person("jack",12)); ts.add(new Person("Nikk",13)); } } class Person implements Comparable{ String name; int age; public Person(String name,int age){ this.name = name; this.age = age; } public int compareTo(Person o){ return this.age - o.age; } } //方法二:使用匿名内部类的方式 public class Program{ public static void main(String[] args){ TreeSet ts = new TreeSet(new Comparable{ compareTo(Peoson o){ return this.age - o.age; } }); ts.add(new Person("jack",12)); ts.add(new Person("Nikk",13)); } } class Person{ String name; int age; public Person(String name,int age){ this.name = name; this.age = age; } }
-
-
-
-
双列集合Map
Map集合中存储的是键值对,访问元素时通过指定的KEY就可以访问Value
常用方法如下:
方法 说明 void put(Object key,Object value) 向集合中存入键值对 Object get(Object key) 通过key获取value boolean containsKey(Object key) 判断是否包含key boolean containsValue(Object value) 判断是否包含value Set keySet() 返回一个Set集合类型的key集合 Collection values() 返回这个映射中包含的值的Collection视图 Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的set视图 -
Hashtable
与HashMap类似,区别在与Hashtable是线程安全的,但是存取速度很慢
Hashtable有一个子类Properties,主要用于存储字符串类型的键和值
//properties对象的创建 Properties p = newProperties(); p.setProperty("color","green"); //获取所有键的枚举*(老式迭代器) Enumeration names = p.propertyNames(); while(names.hasMoreElements()){ String key = (String) p.nextElements(); String value = p.getProperty(key); }
-
HashMap
-
存入新元素时,键相同值覆盖
-
遍历方法
//方法一:通过key集合获取 Map map = new HashMap(); map.put("1","jack"); map.put("2","rose"); //获取key的集合 Set keys = map.keySet(); Iterator it = keys.iterator(); while(it.hasNext()){ Object key = it.next(); Object value = map.get(key); } //方法二:通过values()获取(弊端:不能获取对应的key)
-
-
TreeMap
- TreeMap中元素的key通过某种顺序通过二叉树来保存
-
-
File类
-
路径分割符\ 多个路径拼接;
-
File类是对一个文件或者目录的抽取
-
常用的方法
方法名 说明 boolean exists() 判断指定的路径下有没有文件(夹)的存在 boolean isFile() 判断指定的路径是否为文件 boolean isDirectory() 判断指定的路径是否为文件夹 boolean mkdir() 创建一级目录 boolean mkdirs() 创建多级目录 boolean createNewFile() 创建新文件 boolean isHidden() 文件是否隐藏 boolean canRead() 文件是否可读 boolean canWrite() 文件是否可写 boolean canExcute() 文件是否可以操作 long length() 获取指定路径的文件的长度 String getName() 获取文件的名字 String getPath() 获取路径的字符串形式 String getAbsolutePath() 获取绝对路径的字符串形式 String getPartent() 获取父目录的字符串形式 File getParentFile() 获取父目录的File形式 long lastModified() 获取文件的最后修改时间 boolean setReadOnly() 将文件设置为只读类型 boolean setWritable(booean)
setReadable(~)设置文件的读写性 boolean delete() 删除指定路径文件(不进回收站) String[] list() 返回目录下所有文件(夹)路径的数组 File[] listFiles() String[] files = file.list(new FilenameFilter(){ //这里写过滤条件 //File dir; //文件的父目录 //String name; //文件名 @Override public boolean accept(File dir,String name){ return name.endWith(".txt")); //return name. } });
-
IO流
-
字节流
-
InputStream抽象类
常用实现类有FileInputStream和BufferedInputStream
InputStream包含了四个常用的方法
方法 说明 int read() 从输入流读取到一个8位的字节转换为整数并返回 int read(byte[] b) 从输入流中读取若干个字节保存在数组b中,返回读取字节数 int read(byte[] b,int off,int len) off表示数组开始保存数据的起始下标,len表示读取的字节数目 void close 关闭输入流并释放资源 -
OutputStream抽象类
常用实现类有FileOutputStream和BufferedOutputStream
包含了五个常用的方法
方法 void write(int b) void write(byte[] b) void write(byte[] b,int off,int len) void flush() void close() -
FileInput Stream实例
//创建文件字节输入输出流 FileInputStream is = new FileInputStream("jjii.txt"); FileOutputStream os = new FileOutputStream("iijj.txt"); //FileOutputStream os = new FileOutoutStream(path,true意为是否拼接); //定义变量记录每次读取的数据 int b = 0; //byte[] b = new byte[1024]; while(true){ //in.read(b); b = in.read(); if(b == -1) break; os.write(b); os.flush(); } is.close(); os.close();
-
-
字符流
-
Reader
FileReader
-
Writer
FileWriter
-
使用方法与字节流相似,区别在于使用char[]来存储元素
-
-
字节字符转换输入输出流
-
InputStreamReader与OutputStreamWriter
InputStreamReader is = new InputStreamReader(new FileInputStream(path),"utf8") char[] contents = new char[10]; int length = 0; while((length = reader.read(contents)) != -1) { System.out.print(new String(contents, 0, length)); } writer = new OutputStreamWriter(new FileOutputStream("file\\test2", true), "utf-8"); writer.write("鱼香肉丝、宫保鸡丁、锅包肉、蒸羊羔、蒸熊掌..."); writer.flush();
-
-
System
PrintStream
-
缓冲区
/* * 关于缓冲区 * @author luds */ public class BufferDemo1 { public static void main(String[] args) { // 缓冲区对象,不是通过new进行实例化获取的。而是通过类提供的一个静态方法来获取的。 ByteBuffer buffer = ByteBuffer.allocate(1024); showInfo(buffer, "allocate"); // 使用put方法,往缓冲区放数据 buffer.put("hello".getBytes()); showInfo(buffer, "put"); // 切换成读模式 buffer.flip(); showInfo(buffer, "flip"); // 读取数据 byte[] dst = new byte[buffer.limit()]; buffer.get(dst); showInfo(buffer, "get"); // 重新读取 buffer.rewind(); showInfo(buffer, "rewind"); // 清空缓冲区 buffer.clear(); showInfo(buffer, "clear"); dst = new byte[5]; buffer.get(dst); System.out.println(new String(dst)); } private static void showInfo(ByteBuffer buffer, String operation) { System.out.println(operation + "()方法之后:"); System.out.println("capacity: " + buffer.capacity()); System.out.println("limit: " + buffer.limit()); System.out.println("position: " + buffer.position()); System.out.println("--------------------------------"); } } public class BufferDemo2 { public static void main(String[] args) { ByteBuffer buffer = ByteBuffer.allocate(1024); System.out.println("allocate()方法之后:"); System.out.println("capacity: " + buffer.capacity()); System.out.println("limit: " + buffer.limit()); System.out.println("position: " + buffer.position()); System.out.println("--------------------------------"); buffer.put("hello".getBytes()); System.out.println("put()方法之后:"); System.out.println("capacity: " + buffer.capacity()); System.out.println("limit: " + buffer.limit()); System.out.println("position: " + buffer.position()); System.out.println("--------------------------------"); // 切换成读模式 buffer.flip(); byte[] dst = new byte[2]; buffer.get(dst); System.out.println(new String(dst)); System.out.println("get()方法之后:"); System.out.println("capacity: " + buffer.capacity()); System.out.println("limit: " + buffer.limit()); System.out.println("position: " + buffer.position()); System.out.println("--------------------------------"); // 在指定的position做一个标记 buffer.mark(); buffer.get(dst); System.out.println(new String(dst)); System.out.println("第二次get()方法之后:"); System.out.println("capacity: " + buffer.capacity()); System.out.println("limit: " + buffer.limit()); System.out.println("position: " + buffer.position()); System.out.println("--------------------------------"); // 将position的位置重置为mark的位置 buffer.reset(); System.out.println("reset()方法之后:"); System.out.println("capacity: " + buffer.capacity()); System.out.println("limit: " + buffer.limit()); System.out.println("position: " + buffer.position()); System.out.println("--------------------------------"); buffer.get(dst); System.out.println(new String(dst)); } } public class BufferDemo3 { public static void main(String[] args) { // 获取一个直接缓冲区 ByteBuffer buffer = ByteBuffer.allocateDirect(1024); // 验证一个缓冲区是不是直接缓冲区 System.out.println(buffer.isDirect()); } }
-
通道
public class ChannelDemo1 { public static void main(String[] args) throws IOException { // 需求:复制文件。 long time1 = System.currentTimeMillis(); // channel1(); // 2191, 2459, 1675, 2383 // channel2(); // 672, 556, 584, 563 channel3(); long time2 = System.currentTimeMillis(); System.out.println(time2 - time1); } public static void channel3() throws IOException { FileChannel inChannel = FileChannel.open(Paths.get("C:\\Users\\luds\\Desktop\\1.mp4"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("C:\\Users\\luds\\Desktop\\3.mp4"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); // 通道之间的数据传输 // inChannel.transferTo(0, inChannel.size(), outChannel); outChannel.transferFrom(inChannel, 0, inChannel.size()); inChannel.close(); outChannel.close(); } /** * 2. 使用Channel提供的一个静态方法open() * @throws IOException */ public static void channel2() throws IOException { // 获取一个用来读取文件内容的通道 // Path: 用来描述一个文件的路径,Paths.get() FileChannel inChannel = FileChannel.open(Paths.get("C:\\Users\\luds\\Desktop\\1.mp4"), StandardOpenOption.READ); FileChannel outChannel = FileChannel.open(Paths.get("C:\\Users\\luds\\Desktop\\3.mp4"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE); // 使用直接缓冲区: // 内存映射文件: MappedByteBuffer inBuffer = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size()); MappedByteBuffer outBuffer = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size()); // 直接缓冲区数据的读写 byte[] dst = new byte[inBuffer.limit()]; inBuffer.get(dst); outBuffer.put(dst); inChannel.close(); outChannel.close(); } /** * 1. 使用支持通道的类 */ public static void channel1() { FileInputStream fis = null; FileOutputStream fos = null; FileChannel inChannel = null; FileChannel outChannel = null; try { fis = new FileInputStream("C:\\Users\\luds\\Desktop\\1.mp4"); fos = new FileOutputStream("C:\\Users\\luds\\Desktop\\2.mp4"); // 获取通道 inChannel = fis.getChannel(); outChannel = fos.getChannel(); // 1. 获取缓冲区 ByteBuffer buffer = ByteBuffer.allocate(1024); // 2. 将通道中的数据读取到缓冲区,如果返回-1说明读取结束 while (inChannel.read(buffer) != -1) { // 将buffer切换成读模式 buffer.flip(); // 3. 将缓冲区中的数据写出来 outChannel.write(buffer); // 4. 清空缓冲区的数据 buffer.clear(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (inChannel != null) { try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if (outChannel != null) { try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } } public class Program { public static void main(String[] args) throws IOException { // FileChannel inChannel = FileChannel.open(Paths.get("file\\test"), StandardOpenOption.READ); // 将一个通道inChannal中的数据读取到多个缓冲区。 ByteBuffer buffer1 = ByteBuffer.allocate(128); ByteBuffer buffer2 = ByteBuffer.allocate(128); ByteBuffer[] buffers = { buffer1, buffer2 }; inChannel.read(buffers); for (ByteBuffer b : buffers) { b.flip(); } System.out.println(new String(buffer1.array(), 0, buffer1.limit())); System.out.println("------------------------"); System.out.println(new String(buffer2.array(), 0, buffer2.limit())); // 打开通道 FileChannel outChannel = FileChannel.open(Paths.get("file\\test3"), StandardOpenOption.WRITE, StandardOpenOption.CREATE); // 聚合写入 outChannel.write(buffers); } }
-
/** * 字符集(Charset): * * 编码:由字符串转成字节数组。 * 解码:由字节数组转成字符串。 */ public class Program1 { public static void main(String[] args) throws CharacterCodingException { // 通过名字,获取指定的字符集 Charset cs = Charset.forName("GBK"); CharBuffer buffer = CharBuffer.allocate(1024); buffer.put("你好,师妹"); buffer.flip(); // 编码器: // 获取编码器: CharsetEncoder encoder = cs.newEncoder(); ByteBuffer byteBuffer = encoder.encode(buffer); // 解码器: // CharsetDecoder decoder = cs.newDecoder(); // CharBuffer cb = decoder.decode(byteBuffer); // System.out.println(cb.toString()); System.out.println("-------------------"); CharBuffer cb2 = Charset.forName("GBK").newDecoder().decode(byteBuffer); System.out.println(cb2.toString()); System.out.println("------------"); } public static void showAll() { Map<String, Charset> map = Charset.availableCharsets(); Set<String> keys = map.keySet(); for (String k : keys) { System.out.println(k); } } }