自定义泛型类
public class Order<T> {
T temp;
public Order(T temp) {
this.temp = temp;
}
}
自定义泛型方法
public static <E>List<E> MyArrayToList(E[] arr) {
ArrayList<E> list = new ArrayList<>();
for (E e : arr) {
list.add(e);
}
return list;
}
调用
Order<String> order = new Order<>("hello");
Integer[] arr = new Integer[]{1, 2, 3, 4, 5};
List<Integer> list = order.MyArrayToList(arr);
System.out.println(list);
泛型的继承
通配符 ?
使用原因
G<A> 与 G<B> 不具备子父类的关系,给方法的通用性带来阻碍
@Test
public void test3() {
List<Object> list1 = null;
List<String> list2 = null;
List<?> list = null;// 不能向 list 添加数据,但是可以添加 null
list = list2;
}
// 此方法即能让 list1 传参,也能让 list2 传参
public void method(List<?> list) {
for (Object obj : list) {
System.out.println(list);
}
}
有限制条件的通配符的使用
// 可以看成 Order 或者 Order 的子类 的父类
List<? extends Order> list1 = null;
// 可以看成 Order 或者 Order 的父类 的父类
List<? super Order> list2 = null;
FILE 类
构造器
常用方法
注意:在 Windows 中,renameTo 方法需要保证调用该方法的 File 对象存在并且 dest 不存在
IO 流的分类
操作文件四部曲
- 创造 File 对象
- 造流
- 操作文件
- 关闭流
FileReader 读文件
方式一:每次读取1个字符
FileReader fileReader = null;
try {
File file = new File("HelloWorld.txt");
fileReader = new FileReader(file);
int data;
while ((data = fileReader.read()) != -1) {
System.out.print((char) data);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
方式二:每次读取 charBuffer.length() 个字符
FileReader fileReader = null;
try {
File file = new File("HelloWorld.txt");
fileReader = new FileReader(file);
char[] charBuffer = new char[5];// 每次读取5个字符
int len;
while ((len = fileReader.read(charBuffer)) != -1) {
for (int i = 0; i < len; i++) {
System.out.print(charBuffer[i]);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
FileWriter 写文件
FileWriter fileWriter = null;
try {
// append 默认 false,即不追加
fileWriter = new FileWriter("007.txt", false);
fileWriter.write("0100001010100100101");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
缓冲流
File srcFile = new File("D:\\浏览器下载\\白鹤梁神女.jpg");
File destFile = new File("D:\\浏览器下载\\白鹤梁神女1.jpg");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile);
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
byte[] byteBuffer = new byte[10];
int len;
while ((len = bis.read(byteBuffer)) != -1) {
bos.write(byteBuffer, 0, len);
}
System.out.println("复制成功!!!");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
转换流
InputStreamReader isr = null;
try {
FileInputStream fis = new FileInputStream("HelloWorld.txt");
isr = new InputStreamReader(fis, "UTF-8");
char[] cbuf = new char[5];
int len;
while ((len = isr.read(cbuf)) != -1) {
String str = new String(cbuf, 0, len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
标准输入、输出流
System.in --> 转换流 --> 缓冲流
可以通过 SetIn()、SetOut() 等方法改变流的方向(默认键盘输入,控制台输出)
打印流
print、println
数据流
DataInputStream、DataOutputStream
对象流
- 序列化:用 ObjectOutputStream 类保存基本类型数据或对象的机制
- 反序列化:用 ObjectInputStream 类读取基本类型数据或对象的机制
对象需要实现 Serializable 接口并有一个 serialVersionUID (序列版本号)全局常量,其所有属性也必须是可序列化的
Serializable 是一个标识接口,里面什么都没有
ObjectOutputStream 和 ObjectInputStream 不能序列化 static 和 transient 修饰的成员变量
RandomAccessFile
如果 RandomAccessFile 作为输出流时,会对原有内容进行覆盖而不是对原有文件进行覆盖
网络编程
InetAddress
TCP 网络编程
以客户端向服务端发送文件,发送完毕后服务端向客户端传递信息为例
/**
* client
*/
@Test
public void client() {
Socket socket = null;
OutputStream os = null;
FileInputStream fis = null;
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
// 一、创建 Socket 对象,指明服务端的 IP 和端口号
socket = new Socket(InetAddress.getByName("127.0.0.1"), 8991);
// 二、获取一个输出流,用于输出数据
os = socket.getOutputStream();
// 三、创建一个文件流,用于文件的读取
fis = new FileInputStream(new File("D:\\1.jpg"));
// 四、文件的读取操作
byte[] buffer = new byte[20];
int len;
while ((len = fis.read(buffer)) != -1) {
os.write(buffer, 0, len);
}
// 五、关闭数据输出
socket.shutdownOutput();
// System.out.println("发送文件成功!");
// 六、获取一个输入流,用于服务端向客户端输入数据
is = socket.getInputStream();
// 七、创建一个 ByteArrayOutputStream 流对象,用于文件的传输
baos = new ByteArrayOutputStream();
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* server
*/
@Test
public void server() {
ServerSocket serverSocket = null;
Socket socket = null;
InputStream is = null;
FileOutputStream fos = null;
OutputStream os = null;
try {
// 一、以一个服务器端口号创建一个 ServerSocket,用于等待客户端连接
serverSocket = new ServerSocket(8991);
// 二、获取一个 Socket 对象
socket = serverSocket.accept();
// 三、获取一个输入流,用于输入数据
is = socket.getInputStream();
// 四、创建一个文件输出流对象,用于文件的写入
fos = new FileOutputStream(new File("D:\\3.jpg"));
// 五、文件的写入操作
byte[] buffer = new byte[20];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
// System.out.println("接收客户端文件并复制成功!");
// 六、获取一个输出流,用于传送数据给客户端
os = socket.getOutputStream();
os.write("服务端已收到客户端的传输文件".getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
UDP 网络编程
// 发送端
@Test
public void sender() {
DatagramSocket socket = null;
try {
// 一、创建 UDP 数据报套接字
socket = new DatagramSocket();
// 二、创建 DatagramPacket 对象,其封装了 UDP 数据报,发送端和接收端的 IP 地址和端口号
String str = "UDP传送的数据";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getLocalHost();
DatagramPacket packet = new DatagramPacket(data, 0,
data.length, inet, 9090);
// 三、将 DatagramPacket 对象发送出去
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 四、关闭资源
if (socket != null)
socket.close();
}
}
// 接收端
@Test
public void receiver() {
DatagramSocket socket = null;
try {
// 一、根据接收端端口号创建 UDP 数据报套接字
socket = new DatagramSocket(9090);
// 二、创建 DatagramPacket 对象,指定接收数据的大小
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 三、接收来自发送端的数据
socket.receive(packet);
// 四、输出获取到的数据
System.out.println(new String(packet.getData()));
} catch (IOException e) {
e.printStackTrace();
} finally {
// 五、关闭资源
if (socket != null)
socket.close();
}
}
注意:由于 String(byte[] ascii, int hibyte) 构造方法已经被弃用,使用该方式生成的字符串会出现乱码的情况
URL 编程
URL url = null;
HttpURLConnection urlConnection = null;
InputStream is = null;
try {
// 一、得到 URL 对象
url = new URL("http://localhost:8080/examples/beauty.jpg");
// 二、请求连接
urlConnection = (HttpURLConnection) url.openConnection();
// 三、获取连接
urlConnection.connect();
// 四、得到输入流
is = urlConnection.getInputStream();
// 接下来是对获取到的文件的具体操作
} catch (IOException e) {
e.printStackTrace();
} finally {
// 五、资源的关闭
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}