JavaSE回顾笔记Ⅲ
前言,,懒得写了,去看2吧,开头有几句废话。
day13和上一个重复,是因为这一个是完全自学的一个章节,因为并没什么用,但是很感兴趣就简单看了一下。因为强迫症,不想向后顺延,就放前面啦啦啦~~
Day13【图形界面】
13.1监听接口、JFrame、JButton
GUI-Graphic User Interface 图形用户界面
1.ActionListener接口:public interface ActionListener extends EventListener
创建一个匿名类实现,当按钮被点击时,actionPerformed方法就会被调用
成员方法:
void actionPerformed(ActionEvent e) 发生动作时调用。
2.KeyListener接口:public interface KeyListener extends EventListener
用于接收键盘事件(按键)的侦听器界面
成员方法:
void keyPressed(KeyEvent e) 按下键时调用。
void keyReleased(KeyEvent e) 当键已被释放时调用。
void keyTyped(KeyEvent e) 键入键时调用。
KeyEvent类:
public class KeyEvent extends InputEvent指示组件中发生击键的事件。
成员方法:
char getKeyChar() 返回与此事件中的键相关联的字符。
int getKeyCode() 返回与此事件中的键相关联的整数keyCode。
成员变量:
有大量的静态final成员变量,如VK_A等等。。。。
3.MouseListener类:public interface MouseListener extends EventListener
用于在组件上接收 按,释放,单击 进入或离开组件等鼠标事件。但是要跟踪鼠标移动和鼠标拖动,请使用MouseMotionListener
成员方法:
void mouseClicked(MouseEvent e) 在组件上单击(按下并释放)鼠标按钮时调用。
void mouseEntered(MouseEvent e) 当鼠标进入组件时调用。
void mouseExited(MouseEvent e) 当鼠标退出组件时调用。
void mousePressed(MouseEvent e) 在组件上按下鼠标按钮时调用。
void mouseReleased(MouseEvent e) 在组件上释放鼠标按钮时调用。
4.MouseAdapter类:public abstract class MouseAdapter extends Object implements MouseListener, MouseWheelListener, MouseMotionListener
用于接收鼠标事件的抽象适配器类,这个类中的方法不是抽象方法,且方法体是空的,因此可以只选择性的覆写需要的方法。
成员方法:
void mouseClicked(MouseEvent e) 在组件上单击(按下并释放)鼠标按钮时调用。
void mouseDragged(MouseEvent e) 在组件上按下鼠标按钮然后拖动时调用。
void mouseEntered(MouseEvent e) 当鼠标进入组件时调用。
void mouseExited(MouseEvent e) 当鼠标退出组件时调用。
void mouseMoved(MouseEvent e) 当鼠标光标移动到组件上但没有按钮被按下时调用。
void mousePressed(MouseEvent e) 在组件上按下鼠标按钮时调用。
void mouseReleased(MouseEvent e) 在组件上释放鼠标按钮时调用。
void mouseWheelMoved(MouseWheelEvent e) 当鼠标滚轮旋转时调用。
2.JFrame是GUI中的容器javax.swing.JFrame
构造方法:
JFrame() 构造一个最初不可见的新框架。
JFrame(String title) 创建一个新的,最初不可见的Frame与指定的标题。
成员方法:
void setLocation(int x,int y)将此组件移动到新位置。
void setBounds(int x,int y,int width,int height)移动并调整此组件的大小。
void setSize(int width, int height) 调整此组件的大小
int getX()返回组件原点的当前X坐标
int getY()返回组件原点的当前Y坐标
void add(PopupMenu popup) 将指定的弹出菜单添加到组件。
public Component add(Component comp,int index)将指定组件添加到此容器的给定位置上。
void setLayout(LayoutManager manager)设置LayoutManager,被contentPane以有条件地将呼叫转发到contentPane//传null可设定绝对位置,容器上的组件都需要指定位置和大小
void setDefaultCloseOperation(int operation) 设置用户在此框架上启动“关闭”时默认执行的操作。
void setVisible(boolean b)显示或隐藏此窗口//会对所有的组件进行渲染,所以一定要放在最后面
void addKeyListener(KeyListener l)添加一个键盘监听
void setFocusable(boolean focusable)将此组件的可聚焦状态设置为指定的值.此值覆盖组件的默认焦点。
void setResizable(boolean resizable)设置此窗体是否可由用户调整大小。
void setMenuBar(MenuBar mb)将此窗体的菜单栏设置为指定的菜单栏。
3.JButton是最常见的组件-按钮javax.swing.JButton
构造方法:
JButton() 创建一个没有设置文本或图标的按钮。
JButton(String text) 创建一个带文本的按钮。
JButton(String text, Icon icon) 创建一个带有初始文本和图标的按钮。
成员方法:
void setBounds(int x, int y, int width, int height) 移动并调整此组件的大小。
void addActionListener(ActionListener l)添加一个按钮点击监听
void setText(String text)设置按钮的文本。
public void setToolTipText(String text)注册要在工具提示中显示的文本。光标处于该组件上时显示该文本。
13.2JLabel、ImageIcon、JDialog
1.JLabel类:javax.swing.JLabel
用于短文本字符串或图像或两者的显示区域。
构造方法:
JLabel() 创建一个没有图像的 JLabel实例,并为标题创建一个空字符串。
成员方法:
void setIcon(Icon icon) 定义该组件将显示的图标。
void setBounds(int x,int y,int width,int height)移动并调整此组件的大小。
void setLocation(int x,int y)将此组件移动到新位置。
void addMouseListener(MouseListener l) 添加一个鼠标监听
2.ImageIcon类:javax.swing.ImageIcon
从图像绘制图标的图标界面的实现
构造方法:
ImageIcon(String filename) 从指定的文件创建一个ImageIcon。
成员方法:
int getIconHeight() 获取图标的高度。
int getIconWidth() 获取图标的宽度。
3.JDialog类:javax.swing.JDialog
JDialog也是窗体型容器,右上角没有最大和最小化按钮
JDialog() 创建一个没有标题并且没有指定 Frame 所有者的无模式对话框。
JDialog(Frame owner, String title, boolean modal) 创建一个具有指定标题、所有者 Frame 和模式的对话框。
当一个对话框被设置为模态的时候,其背后的父窗体,是不能被激活的,除非该对话框被关闭
void setModalityType(Dialog.ModalityType type)
APPLICATION_MODAL
对话框阻塞同一 Java 应用程序中的所有顶层窗口(它自己的子层次结构中的顶层窗口除外)。
DOCUMENT_MODAL
对话框阻塞对同一文档中所有顶层窗口的输入(它自己的子层次结构中的顶层窗口除外)。
MODELESS
对话框不阻塞任何顶层窗口。
TOOLKIT_MODAL
对话框阻塞从同一工具包运行所有顶层窗口(它自己的子层次结构中的顶层窗口除外)。
13.3布局器
1.布局器是用在容器上的。 用来决定容器上的组件摆放的位置和大小
void setLayout(LayoutManager manager)//需要new对象
2.绝对定位:null
绝对定位就是指不使用布局器,组件的位置和大小需要单独指定
3.顺序布局器:FlowLayout
容器上的组件水平摆放,加入到容器即可,无需单独指定大小和位置
4.边界布局器:BorderLayout
容器上的组件按照上北 下南 左西 右东 中的顺序摆放,加入到容器的时候,需要指定位置
5.网格布局器:GridLayout
要在创建事传入行列参数
6.卡片布局:CardLayout
可以设置间距
7.注意:
void setPreferredSize(Dimension preferredSize)设置此组件的首选大小。
13.4组件
1.JLabel用于显示文字和图片
2.JButton 普通按钮
3.JCheckBox 复选框
public void setSelected(boolean b)设置按钮的状态
public boolean isSelected()返回按钮的状态。
4.JRadioButton 单选框
public boolean isSelected()返回按钮的状态。
5.ButtonGroup 创建一个互斥按钮包含JRadioButton等
void add(AbstractButton b) 将按钮添加到组中。
6.JComboBox 下拉框
Object getSelectedItem() 返回当前所选项。
void setSelectedItem(Object anObject) 将组合框显示区域中所选项设置为参数中的对象。
7.JOptionPane 用于弹出对话框
static int showConfirmDialog(Component parentComponent, Object message)
调出带有选项 Yes、No 和 Cancel 的对话框
static String showInputDialog(Component parentComponent, Object message)
显示请求用户输入内容的问题消息对话框
static void showMessageDialog(Component parentComponent, Object message)
调出标题为 "Message" 的信息消息对话框。
8.JTextField 输入框
JTextField 是单行文本框,如果要输入多行数据,请使用JTextArea
public void setText(String t) 设置文本;null或空 删除文本
public String getText() 获取文本
public void grabFocus()请求此 Component 获取输入焦点
9.JTextArea:文本域。
和文本框JTextField不同的是,文本域可以输入多行数据
如果要给文本域初始文本,通过\n来实现换行效果
void append(String str) 将给定文本追加到文档结尾。
void setLineWrap(boolean wrap) 设置文本区的换行策略。
10.JPasswordField 密码框
char[] getPassword() 返回此 TextComponent 中所包含的文本。
11.JProgressBar进度条
void setMaximum(int n) 将进度条的最大值设置为 n。
void setValue(int n) 将进度条的当前值设置为 n。
void setStringPainted(boolean b) 设置进度条是否应该呈现进度。
12.JFileChooser 文件选择器
int showOpenDialog(Component parent) 弹出一个打开文件选择器对话框。
int showSaveDialog(Component parent) 弹出一个保存文件选择器对话框。
13.5面板
1.JPanel:基本面板
面板和JFrame一样都是容器,不过面板一般用来充当中间容器,把组件放在面板上,然后再把面板放在窗体上。一旦移动一个面板,其上面的组件,就会全部统一跟着移动,采用这种方式,便于进行整体界面的设计
2.ContentPane
JFrame上有一层面板,叫做ContentPane,平时通过f.add()向JFrame增加组件,其实是向JFrame上的 ContentPane加东西
void setContentPane(Container contentPane)
JFrame方法,将容器contentPane设置为JFramed对象的ContentPane。
3.SplitPanel
JSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent)
创建一个具有指定方向和不连续重绘的指定组件的新 JSplitPane。
void setDividerLocation(int location) 设置分隔条的位置。
4.JScrollPane
使用带滚动条的面板有两种方式
1. 在创建JScrollPane,把组件作为参数传进去
JScrollPane(Component view)
创建一个显示指定组件内容的 JScrollPane,只要组件的内容超过视图大小就会显示水平和垂直滚动条。
2. 希望带滚动条的面板显示其他组件的时候,调用setViewportView
void setViewportView(Component view)
创建一个视口(如果有必要)并设置其视图。
5.TabbedPanel
允许用户通过单击具有给定标题和/或图标的选项卡,在一组组件之间进行切换。
Component add(Component component) 添加一个 component,其选项卡的默认值为调用 component.getName 返回的组件的名称。
void setTitleAt(int index, String title) 将 index 位置的标题设置为 title,它可以为 null。
void setIconAt(int index, Icon icon) 将 index 位置的图标设置为 icon,它可以为 null。
6.CardLayout
容器的布局管理器。它将容器中的每个组件看作一张卡片。一次只能看到一张卡片,容器则充当卡片的堆栈。
CardLayout(int hgap, int vgap) 创建一个具有指定水平间距和垂直间距的新卡片布局。
void show(Container parent, String name) 翻转到使用 addLayoutComponent 添加到此布局的具有指定 name 的组件。
13.6菜单栏、工具栏
1.菜单栏:
JMenuBar:菜单栏
JMenuBar() 创建新的菜单栏
JMenu add(JMenu c) 将指定的菜单追加到菜单栏的末尾。
JFrame对象:
public void setMenuBar(MenuBar mb)将此窗体的菜单栏设置为指定的菜单栏。
JMenu:菜单
JMenu(String s) 构造一个新 JMenu,用提供的字符串作为其文本
JMenuItem add(JMenuItem menuItem) 将某个菜单项追加到此菜单的末尾。
void addSeparator() 将新分隔符追加到菜单的末尾。
JMenuItem:菜单项
JMenuItem(String text) 创建带有指定文本的 JMenuItem。
2.工具栏
JToolBar(String name) 创建一个具有指定 name 的新工具栏。
public Component add(多个重载方法)
void setFloatable(boolean b) 设置工具栏是否可以移动
JButton对象:
public void setToolTipText(String text)注册要在工具提示中显示的文本。光标处于该组件上时显示该文本。
13.7表格
1.JTable基本表格
public JTable(Object[][] rowData,Object[] columnNames)构造一个 JTable 来显示二维数组 rowData 中的值,其标题为 columnNames。
标题默认隐藏,除非将其加入到JScrollPane,后再加入到JFrame
void setSelectionMode(int selectionMode) 设置选择模式。
设置列宽度:JTable对象.方法1.方法2.法3
TableColumnModel getColumnModel() 返回包含此表所有列信息的 TableColumnModel。
TableColumn getColumn(int columnIndex) 返回 columnIndex 位置列的 TableColumn 对象。
void setPreferredWidth(int preferredWidth) 将此列的首选宽度设置为 preferredWidth。
2.TableModel:
数据和显示分离开来,专门做一个类,用于存放要显示的数据
public class DemoTableModel extends AbstractTableModel {
String[] str1 = new String[] {};
String[][] str2 = new String[][] { {},{}, {} };
// 返回一共有多少行
public int getRowCount() {
// TODO Auto-generated method stub
return str2.length;
}
// 返回一共有多少列
public int getColumnCount() {
// TODO Auto-generated method stub
return str1.length;
}
// 获取每一列的名称
public String getColumnName(int columnIndex) {
// TODO Auto-generated method stub
return columnNames[columnIndex];
}
// 单元格是否可以修改
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
// 每一个单元格里的值
public Object getValueAt(int rowIndex, int columnIndex) {
// TODO Auto-generated method stub
return heros[rowIndex][columnIndex];
}
}
3.通过TableModel与DAO结合显示数据库的信息。
4.通过table可以获取一个 TableSelectionModel,专门用于监听jtable选中项的变化
ListSelectionModel getSelectionModel() 返回用来维持行选择状态的 ListSelectionModel。
ListSelectionModel对象:
void addListSelectionListener(ListSelectionListener x) 将侦听器添加到每次在选择发生更改时都得到通知的列表。
void setSelectionInterval(int index0, int index1) 将选择更改为在 index0 和 index1 之间(包括两者)。
13.8日期控件、设置皮肤
1.swing没有自带的日期控件,需要第三方的类jar包
2.DatePicker
不能设置时间,只能在创建控件的时候传入指定日期
该自定义方法的返回值DatePicker对象,可以直接添加到JFrame中
private static DatePicker getDatePicker() {
final DatePicker datepick;
// 格式
String DefaultFormat = "yyyy-MM-dd HH:mm:ss";
// 当前时间
Date date = new Date();
// 字体
Font font = new Font("Times New Roman", Font.BOLD, 14);
Dimension dimension = new Dimension(177, 24);
int[] hilightDays = { 1, 3, 5, 7 };
int[] disabledDays = { 4, 6, 5, 9 };
datepick = new DatePicker(date, DefaultFormat, font, dimension);
datepick.setLocation(137, 83);
datepick.setBounds(137, 83, 177, 24);
// 设置一个月份中需要高亮显示的日子
datepick.setHightlightdays(hilightDays, Color.red);
// 设置一个月份中不需要的日子,呈灰色显示
datepick.setDisableddays(disabledDays);
// 设置国家
datepick.setLocale(Locale.CHINA);
// 设置时钟面板可见
datepick.setTimePanleVisible(true);
return datepick;
}
3.JXDatePicker
界面比较简约,可以设置日期
JXDatePicker datepick = new JXDatePicker();
// 设置 date日期
datepick.setDate(date);
datepick.setBounds(137, 83, 177, 24);
JFrame对象.add(datepick);
4.设置皮肤
这句话需要加在最前面,如果已经创建了界面,再加这个有时候不能正常起作用。
javax.swing.UIManager.setLookAndFeel("皮肤地址");
13.9swing中的线程
1.三种线程
在Swing程序的开发中,需要建立3种线程的概念
1.初始化线程
初始化线程用于创建各种容器,组件并显示他们,一旦创建并显示,初始化线程的任务就结束了。
2.事件调度线程
通过事件监听的学习,我们了解到Swing是一个事件驱动的模型,所有和事件相关的操作都放是放在事件调度线程(Event Dispatch)中进行的。比如点击一个按钮,对应的ActionListener.actionPerformed 方法中的代码,就是在事件调度线程 Event Dispatch Thread中执行的。
事件调度线程是单线程的。因为 Swing里面的各种组件类都不是线程安全的。如果把组件类设计成为线程安全的,由于Swing事件调度的复杂性,就很有可能导致死锁的发生。为了规避同步问题,以及降低整个Swing设计的复杂度,提高Swing的相应速度,Swing中的 事件调度线程被设计成为了单线程模式,即只有一个线程在负责事件的响应工作。
创建和显示界面的工作,最好也交给事件调度线程
3.长耗时任务线程
有时候需要进行一些长时间的操作,比如访问数据库,文件复制,连接网络,统计文件总数等等。 这些操作就不适合放在事件调度线程中进行,因为占用时间久了,会让使用者感觉界面响应很卡顿。 为了保持界面响应的流畅性,所有长耗时任务都应该放在专门的 长耗时任务线程中进行
//当SwingWorker执行execute的时候,调用默认有10根线程的线程池,执行doInBackground中的代码,
SwingWorker worker = new SwingWorker() {
protected Object doInBackground() throws Exception {
//长耗时任务
return null;
}
};
worker.execute();
Day14【Lambda、函数式接口、Stream】
面向对象思想:
做一件事情,找一个能够解决这个事情的对象,调用对象的方法来完成这件事情
函数式编程思想:
重视的是结果,怎么做事情,不重视完成的过程,找谁来做
14.1Lambda
java 8之后
1.格式:
(参数列表)->{重写抽象方法的方法体}
小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
->是新引入的语法格式,代表指向动作。
大括号内的语法与传统方法体要求基本一致。
2.作用:
简化匿名内部类
3.前提:
必须有接口,接口中有且只能有一个抽象方法(函数式接口@FunctionalInterface)
使用Lambda必须具有上下文推断。也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
4.简化:
1.(参数列表):参数列表的数据类型是可以推导出来的,可以省略
2.(参数列表):参数列表中只有一个参数,()小括号也可以省略,但是参数列表没有参数,()小括号不能省略
3.{重写抽象方法的方法体}:重写的方法体,如果只有一行代码,无论方法是否有返回值{ }和一行代码结束的分号(;)和return关键字可以省略不写,但是他们必须一起省略
14.2函数式接口
1.概念:
接口中有且仅有一个抽象方法的接口
2.注意:
1.接口中没有抽象方法不行
2.接口中除了唯一的抽象方法,还可以包含其他的方法(默认,静态,私有)
3.注解:
@FunctionalInterface:检测接口是否为一个函数式接口
-----------------------------------------------------------
java.util.function
1.Consumer:
1.java.util.function.Consumer<T>
2.void accept(T t) :消费一个指定泛型类型的数据
2.Predicate:
1.java.util.function.Predicate<T>
2.boolean test(T t) 用于对接口指定泛型类型的数据进行判断
3.Function
1.java.util.function.Function<T,R>
2.R apply(T t) 根据参数类型T获取类型R的接口,用于类型转换
4.Supplier
1.java.util.function.Supplier<T>
2.T get() 用来获取一个接口指定泛型类型的数据
5.总结
1.函数式接口一般都作为方法的参数(返回值类型)
2.方法的参数是一个函数式接口,那么我们就可以传递lambda表达式作为接口的一种实现类对象为方法的参数接口变量进行赋值
14.3Stream
java.util.stream.Stream<T>接口
1.概念
在Java8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。可以把集合|数组,转换为Stream流,使用Stream流中的方法,对集合|数组进行操作
2.获取Stream流的方式(重点)
1.使用Collection接口中,定义了一个方法stream,可以把集合转换为Stream流
default Stream<E> stream() 此方法只能Collection接口下的单列集合可以使用
2.使用Stream接口中的方法of,可以把可变参数(数组)转换为Stream流
static <T> Stream<T> of(T... values) 方法的参数是一个可变参数,也可以传递数组
3.把数组转换为Stream流
static <T> Stream<T> of(T... values) 方法的参数是一个可变参数,也可以传递数组
14.4Stream常用API
1.分类
终结方法:返回值类型不再是Stream接口自身类型的方法
非终结方法:返回值类型仍然是Stream接口自身类型的方法,除了终结方法外,其余方法均为非终结方法。
2.forEach:用于遍历Stream流中的元素
void forEach(Consumer<? super T> action) 对此流的每个元素执行操作。
3.count方法:统计个数
long count() 返回此流中的元素数。
4.filter方法:用于过滤Stream流中的元素
Stream<T> filter(Predicate<? super T> predicate)
5.limit方法:获取前n个元素
Stream<T> limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize
截取长度超过流中的个数,会截取全部
6.skip:跳过前n个元素
Stream<T> skip(long n)
skip跳过的元素数量大于流中元素的个数,返回一个没有元素的空流
7.map方法:映射,类型转换
<R> Stream<R> map(Function<? super T,? extends R> mapper)
8.concat方法:组合
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
14.5收集Stream结果
1.把Stream流转换为集合,使用Stream流中的方法:
1.R collect(Collector<?> collector) 把Stream流转换为集合
参数:
Collector是一个接口,需要传递接口的是实现类对象
2.java.util.stream.Collectors:是一个工具类,里边提供的静态方法,可以获取Collector接口的实现类对象
1.static <T> Collector<T,?,List<T>> toList() 返回一个 Collector ,将输入元素累加到一个新的 List (有序,有索引,允许重复)。
2.static <T> Collector<T,?,Set<T>> toSet() 返回一个 Collector ,将输入元素累加到一个新的 Set (没有索引,不允许重复)。
2.把Stream流转换为数组,Stream流中的方法:
1.Object[] toArray() 返回一个包含此流的元素的数组。
2.<A> A[] toArray(IntFunction<A[]> generator) 使用提供的 generator函数返回一个包含此流的元素的数组,以分配返回的数组,以及分区执行或调整大小可能需要的任何其他数组。
toArray(String[]::new).var
Day15【File类、递归、字节流】
15.1File类的介绍
1.java.io.File类
1.文件和目录路径名的抽象表示形式。
2.File类封装了计算机中的文件和文件夹,我们可以通过File类中的方法来操作计算机中的文件和文件夹
3.是一个与系统无关的类,任何的操作系统都可以使用File类中的方法和变量
2.静态的成员变量
1.static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串。
2.static char pathSeparatorChar 与系统有关的路径分隔符。
3.static String separator 与系统有关的默认名称分隔符,为了方便,它被表示为一个字符串。
4.static char separatorChar 与系统有关的默认名称分隔符。
3.路径:
1.绝对路径:以盘符(c:,D:,e:)开始的路径(唯一)
2.相对路径:相对于我们当前项目目录的路径
4.分隔符:
1.路径分隔符 windows系统:分号(;) linux系统:冒号(:)
2.名称分隔符 windows系统:反斜杠(\) linux系统:正斜杠(/)
15.2File的方法
1.构造方法:
File(File parent, String child);
File(String parent, String child);
File(String pathname);
注意:
1.参数传递路径可以是绝对路径,也可以是相对路径
2.参数传递路径可以是以文件结尾的路径,也可以使用以文件夹结尾的路径
3.参数传递路径可以是真实存在的,也可以是不存在;构造方法仅仅是把字符串的路径,封装为File对象,不检查路径的真实情况
2.成员方法:(获取相关)
1.public String getAbsolutePath() :返回此File的绝对路径名字符串。
2.public String getPath() :将此File转换为路径名字符串。
1.传递路径是绝对的就返回绝对的;传递的路径是相对的,就返回相对路径
2.File类重写了Object类的toString方法,实际用的就是这个方法
3.public String getName() :返回由此File表示的文件或目录的名称。
File对象表示的是否是文件,不能根据后缀名确定,有可能是一个文件夹
4.public long length() :返回由此File表示的文件的长度。 不能获取目录的长度。(单位是字节,路径不存在返回0)
3.成员方法:(判断相关)
1.public boolean exists() :此File表示的文件或目录是否实际存在。
2.public boolean isDirectory() :此File表示的是否为目录。
3.public boolean isFile() :此File表示的是否为文件。
构造方法中路径必须是存在的,才能判断路径是文件夹结尾还是文件结尾;否则没有意义,都会返回false
计算机中只有文件和文件夹,所以两个方法互斥
4.成员方法:(创建删除相关)
1.public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
文件存在,不会创建
路径必须存在否则会报异常
2.public boolean mkdir() :创建由此File表示的目录。(只能创建单级)
3.public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录(能创建单级和多级)
文件夹存在或方法中路径不存在,返回false
只能创建文件夹,不能创建文件
4.public boolean delete() :删除由此File表示的文件或目录。
文件夹中有内容时不会删除,删除内容不进回收站
5.成员方法:(目录遍历相关)
1.public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
2.public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
注意:
1.遍历的目录必须是存在的,否则会抛出空指针异常
2.这个方法只能遍历目录,不能遍历文件,否则会抛出空指针异常
15.3递归
1.递归分类:
1.直接递归
2.间接递归
2.注意事项:
1.递归必须有结束的条件,保证递归可以停下来,否则会抛出内存溢出的错误
2.递归有结束的条件,但是递归次数也不能太多,否则会抛出内存溢出的错误
3.构造方法禁止递归
3.什么时候使用递归:
当我们频繁的调用某一个方法,方法的主体不变,每次调用方法的参数改变,就可以使用递归
4.利用递归遍历文件夹和子文件夹中的文件
15.4IO流
1.Java中I/O操作主要是指使用 java.io包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。
2.分类:
根据数据的流向分为:输入流和输出流。(InputStream和OutputStream)
根据数据的类型分为:字节流和字符流。(Reader和Writer
3.IO流中的四个顶层父类:
字节流: InputStream OutputStream
字符流: Reader Writer
4.注意:
1.硬盘中的一切文件数据都是以二进制数字的形式保存,都是一个一个的字节,传输时一样如此。所以,字节流可以传输任意文件数据。
2.任何记事本都有转换的功能,会查询编码表,将二进制数据转化为字符。
3.-128-127之间:查询ASCII,其他数据查询系统默认的编码表(GBK、UTF-8等)
4.文件存储空间默认为从0kb到一个4kb的倍数。
5.GBK中一个中文占两个字节,UTF-8中占用三个字节,Unicode中占四个字节
三个字节或四个字节的汉字可以存储到char数组中的原因是因为:char数组中存取的字节不保括字节序标识。比如'放‘,其Unicode编码为FE FF 65 3E,共四个字节。FE FF表示是Big Endian,也就是高位在前,低位在后;65 3E转化为10进制就是25918,也就是’放‘+0的值,也就是char中存放的值。
15.5字节输出流
1.java.io.OutputStream:字节输出流
此抽象类是表示输出字节流的所有类的超类。
定义了所有字节输出流中共性的成员方法,所有字节输出流都可以使用
2.共性的成员方法:
public void write(byte[] b) :将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。
public abstract void write(int b) :将指定的一个字节输出流。
public void flush() 刷新此输出流并强制写出所有缓冲的输出字节。
public void close() :关闭此输出流并释放与此流相关联的任何系统资源。
3.java.io.FileOutputStream:文件字节输出流 extends OutputStream
1.作用:
把内存中字节写入到硬盘的文件中保存
2.构造方法:
FileOutputStream(File file) (如果已存在,会清空数据)
FileOutputStream(String name)(如果已存在,会清空数据)
FileOutputStream(File file, boolean append)
FileOutputStream(String name, boolean append)
过程:
1.会创建FileOutputStream对象
2.会根据构造方法中传递的文件路径|文件,创建一个新的空白文件
3.会把FileOutputStream对象指向创建好的文件
注意:
true:续写 false:空白文件覆盖
3.使用字节输出流往文件中写数据底层过程
java程序==>JVM==>操作系统(OS)==>调用系统中写数据的方法==>把数据写入到文件中
4.换行:
windows: \r\n
linux: \n
mac: \r Mac OS X开始与Linux统一
15.6字节输入流
1.java.io.InputStream:字节输入流
此抽象类是表示字节输入流的所有类的超类。
定义了所有字节输入流共性的成员方法,所有的字节输入流都可以使用这些方法
流对象只能读取文件,不能读取文件夹
2.共性的成员方法:
1.int read() 从输入流中读取数据的下一个字节。
2.int read(byte[] b)从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
3.void close() 关闭此输入流并释放与该流关联的所有系统资源。
注意:
1.read方法的返回值为每次读取的有效字节个数
2.byte[]起到缓冲作用,把系统读取到的字节,依次存储,再由操作系统一次性的返回jvm,再返回到Java程序中。
3.数组长度一般定义为1024或其倍数。
3.java.io.FileInputStream:文件字节输入流 extends InputStream
把文件中的数据,以字节的方式读取到内存中
构造方法:
FileInputStream(File file)
FileInputStream(String name)
构造方法的作用:
1.会创建FileInputStream对象
2.会把创建好的FileInputStream对象指向要读取文件的第一个字节
注意:
使用构造方法创建对象,如果要读取的文件不存在,会抛出文件找不到异常
使用字节输入流读取文件到内存中底层原理:
java程序==>JVM==>操作系统==>调用系统中读取文件的方法==>读取文件
Day16【字符流、Properties】
16.1字符入流
1.java.io.Reader:字符输入流
用于读取字符流的抽象类,是所有字符输入流的最顶层的父类
定义了所有字符输入流中共性的成员方法,所有的字符输入流都可以使用
2.共性的成员方法:
int read()读取单个字符。
int read(char[] cbuf)将字符读入数组。
void close() 关闭该流并释放与之关联的所有资源。
3.java.io.FileReader:文件字符输入流 extends InputStreamReader(转换流) extends Reader
把文件中的数据以字符的方式读取到内存中
构造方法:
FileReader(File file)
FileReader(String fileName)
FileReader只能读取IDEA默认编码的文件(utf-8)
16.2字符输出流
1.java.io.Writer:字符输出流
写入字符流的抽象类,是所有字符输出流的最顶层的父类
里边定义了所有字符输出流中共性的成员方法,所有的字符输出流都可以使用
2.共性的成员方法:
public abstract void close() :关闭此输出流并释放与此流相关联的任何系统资源。
public abstract void flush() :刷新此输出流并强制任何缓冲的输出字符被写出。
public void write(int c) :写出一个字符。
public void write(char[] cbuf) :将 b.length字符从指定的字符数组写出此输出流。
public abstract void write(char[] b, int off, int len) :从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流。
public void write(String str) :写出一个字符串。
public void write(String str, int off, int len) 写入字符串的某一部分。
3.java.io.FileWriter:文件字符输出流 extends OutputStreamWriter(转换流) extends Writer
把内存中的数据,以字符的方式写入到文件中
构造方法:
FileWriter(File file)
FileWriter(String fileName)
FileWriter(File file, boolean append)
FileWriter(String fileName, boolean append)
构造方法的作用:
1.会创建FileWriter对象
2.会根据构造方法中传递的文件|文件的路径,创建一个新的空白文件
3.会把FileWriter对象,指向空白的文件
注意:
true:续写 false:空白文件覆盖
16.3异常处理
1.JDK7前
1.try...catch...finally
2.对象引用要定义在try外,并赋初始值null;
3.调用close方法前要加非空判断
2.JDK7前后
格式:
try(
//定义流对象,只能定义流对象
//不同对象间用分号分割,所以最后一个不用写
AAA aaa = new AAA(读);
BBB bbb = new BBB(写)
){
可能产生异常的代码
aaa.read();
bbb.write():
}catch(定义一个异常相关的变量,接收异常对象){
异常的处理逻辑
}
注意:
省略finally
在try的后边增加一个(),在()中定义流对象
那么这些流对象的作用域,就在try中有效,执行完try中的代码,会自动帮助我们释放流对象的
16.4Properties集合
1.java.util.Properties集合 extends Hashtable<k,v>双列集合
1.表示了一个持久的属性集,可保存在流中或从流中加载。
2.Properties集合是一个唯一和IO流相结合的集合
3.Properties集合是一个双列集合,可以不用写泛型,默认key和value都是String类型
2.成员方法:
Object setProperty(String key, String value) 往Properties集合中添加键值对,相当于Map集合中的put方法
String getProperty(String key) 根据key获取vlaue,相当于Map集合中的get(key)方法
Set<String> stringPropertyNames() 返回此属性列表中的键集,相当于Map集合中的keySet方法
3.stroe方法:
把集合中的临时数据,持久化存储到硬盘中
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
注意:
OutputStream out:传递字节输出流,不能写中文,会出现乱码,可以传递OutputStream任意的子类对象
Writer writer:传递字符输出流,能写中文,不会出现乱码,可以传递Writer任意的子类对象
String comments:注释,解释说明我们保存的文件是什么用的,一般传递""
注释不能写中文,默认使用Unicode编码,会出现乱码
4.load方法:
把硬盘中保存的键值对文件,读取到内存集合中使用(硬盘-->内存)
void load(InputStream inStream) 传递字节输入流,不能读取含有中文的文件,可以传递InputStream任意的子类对象
void load(Reader reader) 传递字符输入流,可以读取含有中文的文件,可以传递Reader任意的子类对象
注意:
(在Properties集合的配置文件中)
1.可以使用#进行注释,被注释的键值对不会被读取
2.健和值之间可以使用=,空格,冒号等一些符号作为键与值的分割符号
3.健和值默认都是字符串类型,不需要添加引号,否则会画蛇添足
16.5ResourceBundle
1.当资源文件是以.properties结尾的文件时,可以使用JDK提供的另外一个工具类ResourceBundle来对文件进行读取,使得操作更加简单。
2.java.util.ResourceBundle:操作资源的工具类
ResourceBundle是一个抽象类
ResourceBundle类中的静态方法获取ResourceBundle的子类对象
static ResourceBundle getBundle(String baseName)
参数:
String baseName:传递以.properties结尾的文件名称(省略后缀)
注意:
.properties结尾的文件必须放在当前模块的src里边,否则获取对象找不到配置文件,会抛出异常
3.方法:
String getString(String key) 根据配置文件中key,读取配置文件中的value
注意:
配置文件中key和value不要使用中文
Day17【IO流、装饰设计、工具包】
17.1字节缓冲流
1.java.io.BufferedInputStream:字节缓冲输入流 extends InputStream
继承自父类的共性成员方法:
int read()
int read(byte[] b)
void close()
构造方法:
BufferedInputStream(InputStream in) 创建具有默认缓冲区大小的BufferedInputStream对象
BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 对象
InputStream in:传递字节输入流,可以传递InputStream的任意的子类对象,比如FileInputStream对象。缓冲流会给FileInputStream对象增加一个缓冲区(字节数组),提高FileInputStream读取文件的效率。
int size:指定缓冲区的大小(数组的长度),不指定使用默认值(4k)
-----------------------------------------------------------------
2.java.io.BufferedOutputStream:字节缓冲输出流 extends OutputStream
继承自父类的共性成员方法:
public void write(byte[] b)
public void write(byte[] b, int off, int len)
public abstract void write(int b)
public void flush()
public void close()
构造方法:
BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,具有默认缓冲区大小
BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,具有指定缓冲区大小
17.2字符缓冲流
1.java.io.BufferedReader:字符缓冲输入流 extends Reader
继承自父类的共性成员方法:
int read()
int read(char[] cbuf)
void close()
构造方法:
BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz) 创建一个使用指定大小输入缓冲区的缓冲字符输入流。Reader in:传递字符输入流,可以传递Reader的任意的子类对象,比如FileReader,缓冲流就会给FileReader增加一个缓冲区,可以提高FileReader读取数据的效率
特有的成员方法:
String readLine() 读取一个文本行。 一次读取一行数据
通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行(\r\n)。
返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
-----------------------------------------------------------------
2.java.io.BufferedWriter:字符缓冲输出流 extends Writer
继承自父类的共性成员方法:
public abstract void close()
public abstract void flush()
public void write(int c)
public void write(char[] cbuf)
public abstract void write(char[] b, int off, int len)
public void write(String str) :写出一个字符串。
public void write(String str, int off, int len)
构造方法:
BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
特有的成员方法:
void newLine() 写入一个行分隔符。写一个换行,根据系统不同,而写不同的换行符号
17.3转换流
1.字符编码:一套自然语言的字符与二进制数之间的对应规则。编码、解码。
2.字符集:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。
ASCII
ISO-8859-1 单字节编码
GBxxx
GB2312:简体中文码表。 7000多个简体汉字
GBK:目前操作系统默认中文码表(简体,繁体),存储一个中文使用2个字节
GB18030:最新的中文码表。每个字可以由1个、2个或4个字节组成。
Unicode
UTF-8 最常用
128个US-ASCII字符,只需一个字节编码。
拉丁文等字符,需要二个字节编码。
大部分常用字(含中文),使用三个字节编码
其他极少使用的Unicode辅助字符,使用四字节编码。
UTF-16
UTF-32
3.原理:
读取字节流,按照对应字符集转化为字符。
将字符按照对应字符集转化为字节流,写入硬盘。
17.4字符转换流
1.java.io.InputStreamReader:字符转换输入流 extends Reader
继承自父类的共性成员方法:
int read()
int read(char[] cbuf)
void close()
构造方法:
InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。
InputStream in:传递字节输入流,可以传递InputStream的任意的子类对象(读取文件中的字节)
String charsetName:传递编码表名称,不区分大小写,可以传递GBK(gbk),UTF-8(utf-8),...,不写默认使用IDEA的编码UTF-8
2.java.io.OutputStreamWriter:字符转换输出流 extends Writer
继承自父类的共性成员方法:
public abstract void close()
public abstract void flush()
public void write(int c)
public void write(char[] cbuf)
public abstract void write(char[] b, int off, int len)
public void write(String str)
public void write(String str, int off, int len)
构造方法:
OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。
参数:
OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象(把字符转换之后的字节写入到文件中)
String charsetName:传递编码表名称,不区分大小写,可以传递GBK(gbk),UTF-8(utf-8),...,不写默认使用IDEA的编码UTF-8
17.5序列化
1.java.io.ObjectOutputStream:对象的序列化流 extends OutputStream
1.作用:把对象以流的方式写入到文件中保存
2.构造方法:
ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。
OutputStream out:传递字节输出流对象,可以传递OutputStream的任意子类对象
3.特有的成员方法:
void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。
4.异常:NotSerializableException没有序列化异常
类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
Serializable接口是一个标记型接口,类实现了Serializable接口,接口就会给类添加一个标记
当我们进行序列化和反序列化的时候,会检查类上是否有标记,有则序列化成功,没有则序列化失败会抛出异常
2.java.io.ObjectInputStream:对象的反序列化流 extends InputStream
1.作用:把文件中保存的对象以流的方式读取出来使用
2.构造方法:
ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
InputStream in:传递字节输入流,可以传递InputStream的任意子类对象
3.特有的成员方法:
Object readObject() 从 ObjectInputStream 读取对象。
4.前提:
1.类实现Serializable接口
2.类有对应的class文件(类的java文件编译生成的那个)
3.transient
transient:瞬态关键字
被transient关键修饰的变量不能被序列化(有这一项,但值为默认的)
静态变量不属于对象,属于类。也不能被序列化。
4.序列号冲突异常
Serializable接口规定:
可序列化类可以通过静态、最终的 long 型字段显式声明其自己的serialVersionUID
static final long serialVersionUID = 任意值L;
原因:
编译器(javac.exe)会把java文件编译成class文件,并根据类的定义给class文件添加一个序列号。如果修改了类的定义,就会重新生成一个序列号。反序列化时如果序列号不一致,就会抛出InvalidClassException
5.序列化集合:
如果要往文件中存储多个对象,建议创建一个集合,把对象保存到集合中,对集合进行序列化和反序列化。
17.6打印流
1.java.io.PrintStream:字节打印流 extends OutputStream
1.特点:
1.PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
2.与其他输出流不同,PrintStream 永远不会抛出 IOException;创建对象的时候,可能会抛出文件找不到异常
3.PrintStream是打印流,只负责打印(输出),不能读取
2.构造方法:
PrintStream(File file) 打印流的目的地是一个文件
PrintStream(OutputStream out) 打印流的目的地是一个字节输出流
PrintStream(String fileName) 打印流的目的地是一个文件路径
3.成员方法:
1.继承自父类的共性成员方法write:(会查询编码表)
public void write(byte[] b)
public void write(byte[] b, int off, int len)
public abstract void write(int b)
public void flush()
public void close()
2.自己特有的成员方法:print,println写数据,原样输出
void print(Object obj) 可以写任意类型的数据,不换行
void println(Object obj) 可以写任意类型的数据,换行
2.修改输出语句的目的地
使用System类中方法setOut,可以修改输出语句的目的地(控制台)为打印流的目的地
static void setOut(PrintStream out) 重新分配“标准”输出流。
17.7装饰设计
装饰模式可以在不改变原类的基础上对类中的方法进行扩展增强,实现原则为:
1. 装饰类和被装饰类必须实现相同的接口,继承相同的父类
2. 在装饰类中必须传入被装饰类的引用,使用构造方法传递
3. 在装饰类中对需要扩展的方法进行扩展
4. 在装饰类中对不需要扩展的方法调用被装饰类中的同名方法
17.8commons-io工具包
包 | 功能描述 |
---|---|
org.apache.commons.io | 有关Streams、Readers、Writers、Files的工具类 |
org.apache.commons.io.input | 输入流相关的实现类,包含Reader和InputStream |
org.apache.commons.io.output | 输出流相关的实现类,包含Writer和OutputStream |
org.apache.commons.io.serialization | 序列化相关的类 |
1.commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
2.添加第三方jar包到模块中
把jar包复制到指定的Module的lib目录中
将加入到classpath中(idea中,右键选择jar包,Add as Library)
----------------------------------------------------------------------
3.org.apache.commons.io.IOUtils:操作IO流的工具类
1. public static int copy(InputStream in, OutputStream out);把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
2. public static long copyLarge(InputStream in, OutputStream out); 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)
----------------------------------------------------------------------
4.org.apache.commons.io.FileUtils:操作文件的工具类
1.static String readFileToString(File file) 读取一个文件以字符串的形式返回
2.static void writeStringToFile(File file, String data) 把字符串写到一个文件中
3.static void copyFile(File srcFile, File destFile) 文件复制
4.static void copyFileToDirectory(File srcFile, File destDir) 把一个文件复制到一个文件夹
5.static void copyDirectoryToDirectory(File srcDir, File destDir) 文件夹复制
day18【网络编程、TCP协议】
18.1网络编程
1.网络编程:
在一定协议下,实现两台计算机的通信的程序。
三要素:协议、IP地址、端口号
2.软件结构
C/S结构:全称为Client/Server结构,是指客户端和服务器结构。
B/S结构:全称为Browser/Server结构,是指浏览器和服务器结构。
3.网络通信协议
通信协议是计算机必须遵守的规则,协议中对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守,最终完成数据交换。
TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是Internet最基本、最广泛的协议。
udp:面向无连接的协议,通信的双方不用建立连接,可以直接发送数据
好处:效率高,耗资小
弊端:不安全,容易丢失数据
tcp:面向连接协议,客户端和服务器端必须经过3次握手建立逻辑连接,才能通信
好处:安全
弊端:效率低
4.IP地址:
指互联网协议地址(Internet Protocol Address),用来给一个网络中的计算机设备做唯一的编号。
作用:
唯一性,在网络中可以通过ip地址找到另外一台计算机
ipv4:
ip地址由4个字节组成(十进制表示)
ipv6:
ip地址由16个字节组成(十六进制表示)
本机IP地址:
127.0.0.1、 localhost
5.端口号:
逻辑端口,当软件联网时,操作系统分配一个随机端口号
由两个字节组成,0~65535
1024前的被分配给一些已知网络,1024之后为动态端口号。
18.2InetAddress
1.java.net.InetAddress:描述计算机的ip地址
此类表示互联网协议 (IP) 地址。
可以使用InetAddress类中的方法获取到计算机的ip地址
2.静态方法
static InetAddress getLocalHost() 返回本地主机(你自己的电脑的IP地址对象)。
static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。也可以时IP地址和域名
3.非静态方法:
String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
String getHostName() 获取此 IP 地址的主机名。
18.2TCP通信
1.特点:
通过三次握手建立连接,连接成功形成数据传输通道。
通过四次挥手断开连接
基于IO流进行数据传输
传输数据大小没有限制
因为面向连接的协议,速度慢,但是是可靠的协议。
2.客户端:
1.作用:
主动和服务器经过3次握手建立连接通路,给服务器发送数据,读取服务器服务器的数据
2.类:
java.net.Socket:此类实现客户端套接字(套接字)。套接字是两台机器间通信的端点,封装了IP地址和端口号的网络单位。
3.构造方法:
Socket(InetAddress address, int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。
4.成员方法:
OutputStream getOutputStream()返回此套接字的输出流。
InputStream getInputStream() 返回此套接字的输入流。
void shutdownOutput() 禁用此套接字的输出流。
5.注意:
1.创建客户端Socket对象的时候,客户端就会和服务器经过3次握手建立连接通路
服务器已经启动了,服务器地址填写正确:握手成功,创建好Socket对象
服务器没有启动,服务器地址填写错误:握手失败,会抛出连接异常
2.客户端和服务器之间进行数据交互,不能使用自己创建的流对象和本地硬盘文件进行读写,需要使用Socket对象提供的流对象
----------------------------------------------------------------
3.服务器端
1.作用:
接收客户端的请求和客户端经过3次握手建立连接通路;接收客户端发送的数,给客户端发送数据
2.表示服务器的类:
java.net.ServerSocket:此类实现服务器套接字。
3.构造方法:
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。
4.成员方法:
Socket accept() 侦听并接受到此套接字的连接。
5.注意:
1.使用accpet方法,一直监听客户端的请求,有客户端请求服务器,accept方法就会获取到请求的客户端Socket对象
2.服务器没有自己的IO流对象,使用的是客户端的。
3.服务器使用的端口号已经被占用,会报BindException
18.3UDP通信
1.java.net.DatagramPacket 此类表示数据报包。
数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
构造方法:
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将buf数组中长度为 length 的包发送到指定主机上的指定端口号。
DatagramPacket(byte[] buf, int length)
构造 DatagramPacket,用来接收长度为 length 的数据包。
成员方法:
byte[] getData() 返回数据缓冲区。
int getLength() 返回将要发送或接收到的数据的长度。
-----------------------------------------------------------------------------
2.java.net.DatagramSocket 此类表示用来发送和接收数据报包的套接字。
数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
构造方法:
DatagramSocket() 创建数据报套接字并将其绑定到本地主机上的随机端口。
DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。
成员方法
void send(DatagramPacket p) 从此套接字发送数据报包
void receive(DatagramPacket p) 从此套接字接收数据报包。有阻塞功能
InetAddress getAddress() 返回该数据报发送或接收数据报的计算机的IP地址。
int getLength() 返回要发送的数据的长度或接收到的数据的长度。
int getPort() 返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。
-----------------------------------------------------------------------------
3.使用
1.创建DatagramSocket对象
2.创建数据报对象
3.接受或发送数据
4.释放资源
4.注意:
1.最大一次传输64Kb
18.4注意事项
1.文件上传的阻塞问题:
常用的while(len!=-1)判断方法,在对方的网络字输出节流中是无法生效的,也就是并不会在流读取完后,会使len=-1。这会导致陷入死循环。
需要输出流结束后,调用shutdownOutput方法,此方法对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。
2.文件存放:
文件命名:域名+毫秒值+随机数
3.多线程版本服务器:
while(true){
Socket socket = server.accept();
new Thread(()->{
try{
}catch(...){
}
}).start();
}
18.5B/S服务器
1.过程:
浏览器(客户端)通过URL地址,向服务器访问
服务器收到一堆字符串,经处理,得到客户端想要的文件路径
将文件通过网络字节流写到客户端显示
2.URL:统一资源定位符,定义到服务器上某一个资源。
3.使浏览器以html的方式查看:
对象.write("HTTP/1.1 200 OK\r\n".getBytes());
对象.write("Content-Type:text/html\r\n".getBytes());
对象.write("\r\n".getBytes());
4.多次请求:
如果html文件中有多个文件,客户端会根据路径多次请求。
解决方式:添加死循环
Day19【Junit、AIO、Buffer、Channel】
19.1Junit
1.Junit是一个Java语言的单元测试框架,属于第三方工具。
2.使用步骤:
1.导包
2.在要执行的方法上添加一个@Test注解
3.右键运行模块/类/单个被标记的测试方法
3.注意事项:
1.必须是public修饰的,没有返回值,没有参数
2.必须使用JUnit的注解@Test修饰
4.常用注解:
Junit4.x版本
@Before:用来修饰方法,该方法会在每一个测试方法执行之前自动执行一次。
@After:用来修饰方法,该方法会在每一个测试方法执行之后自动执行一次。
@BeforeClass:用来静态修饰方法,该方法会在所有测试方法之前自动执行一次,而且只执行一次。
@AfterClass:用来静态修饰方法,该方法会在所有测试方法之后自动执行一次,而且只执行一次。
Junit5.x版本
@BeforeEach:用来修饰方法,该方法会在每一个测试方法执行之前执行一次。
@AfterEach:用来修饰方法,该方法会在每一个测试方法执行之后执行一次。
@BeforeAll:用来静态修饰方法,该方法会在所有测试方法执行之前执行一次。
@AfterAll:用来静态修饰方法,该方法会在所有测试方法执行之后执行一次
5.Assert类
public static void assertEquals(String message, Object expected, Object actual)
19.2BIO、NIO、AIO
1.概述:
1).BIO:Block(阻塞的) IO——我们之前学的。 【同步、阻塞】
2).NIO:Non-Block(非阻塞的(同步)IO——JDK1.4开始的。 【同步、非阻塞】
3).AIO:Asynchronous(异步-非阻塞)IO——JDK1.7开始 【异步、非阻塞】
2.阻塞、非阻塞、同步、异步
同步与异步(synchronous/asynchronous):同步是一种可靠的有序运行机制,当我们进行同步操作时,后续的任务是等待当前调用返回,才会进行下一步;
而异步则相反,其他任务不需要等待当前调用返回,通常依靠事件、回调等机制来实现任务间次序关系
阻塞与非阻塞:在进行阻塞操作时,当前线程会处于阻塞状态,无法从事其他任务,只有当条件就绪才能继续,
而非阻塞则是不管IO操作是否结束,直接返回,相应操作在后台继续处理
3.概括:
阻塞:等待结果
非阻塞:可以做别的事情
同步:主动获取结果
异步:等待通知结果
4.NIO的三个主要组成部分:
Buffer(缓冲区)、Channel(通道)、Selector(选择器)
19.3Buffer类
1.概述:
java.nio.Buffer(抽象类):用于特定原始类型(基本类型)的数据的容器。后期在会用Channel进行通信时,底层全部使用Buffer。
2.子类:
1.ByteBuffer:里面可以封装一个byte[]数组。【重点掌握】
2.ShortBuffer:里面可以封装一个short[]数组。
3.CharBuffer:里面可以封装一个char[]数组
4.IntBuffer:里面可以封装一个int[]数组。
5.LongBuffer:里面可以封装一个long[]数组。
6.FloatBuffer:里面可以封装一个float[]数组。
7.DoubleBuffer:里面可以封装一个double[]数组。
没有boolean类型对应的Buffer
-------------------------------------------------------------------
1.java.nio.ByteBuffer:字节缓冲区,里边封装了一个byte类型的数组
2.获取ByteBuffer对象:
public static ByteBuffer allocate(int capacity):
使用一个“容量”来创建一个“间接字节缓存区”——程序的“堆”空间中创建。
public static ByteBuffer allocateDirect(int capacity):
使用一个“容量”来创建一个“直接字节缓存区”——系统内存。
public static ByteBuffer wrap(byte[] byteArray):
使用一个“byte[]数组”创建一个“间接字节缓存区”。
3.方法
public ByteBuffer put(byte b):向当前可用位置添加数据。
public ByteBuffer put(byte[] byteArray):向当前可用位置添加一个byte[]数组
public ByteBuffer put(byte[] byteArray,int offset,int len):添加一个byte[]数组的一部分
byte[] array()获取此缓冲区的 byte 数组
-------------------------------------------------------------------
1.容量-capacity:
Buffer所能够包含的元素的最大数量。定义了Buffer后,容量是不可变的。
int capacity() 返回此缓冲区的容量。
2.限制-limit:
表示如果设置“限制为某一个位置,那么此位置后的位置将不可用
public int limit():获取此缓冲区的限制。
public Buffer limit(int newLimit):设置此缓冲区的限制。
3.位置-position:
当前可写入的索引。位置不能小于0,并且不能大于限制
public int position():获取当前可写入位置索引。
public Buffer position(int p):更改当前可写入位置索引。
4.标记-mark
public Buffer mark():设置此缓冲区的标记为当前的position位置。
Buffer reset() 将此缓冲区的位置重置为以前标记的位置。
5.其他方法:
public int remaining():获取position与limit之间的元素数量。
public boolean isReadOnly():获取当前缓冲区是否只读。
public boolean isDirect():获取当前缓冲区是否为直接缓冲区。
public Buffer clear():还原缓冲区的状态。
将position设置为:0
将限制limit设置为容量capacity;
丢弃标记mark。
public Buffer flip():缩小limit的范围。获取读取的有效数据0到position之间的数据
将limit设置为当前position位置
将当前position位置设置为0
丢弃标记
19.4Channel、FileChannel
1.java.nio.channels.Channel(接口):用于 I/O 操作的连接。 表示:通道。
1.它类似于IO流,但比IO流更强大。
2.为所有的原始类型提供(Buffer)缓存支持;
3.字符集编码解决方案(Charset);
4.Channel : 一个新的原始I/O抽象;
5.支持锁和内存映射文件的文件访问接口;
6.提供多路(non-bloking)非阻塞式的高伸缩性网路I/O。
7.IO流是“单向”的,Channel是“双向的”
8.Channel全部使用Buffer实现读、写
2.在Java NIO中的Channel主要有如下几种类型:
FileChannel:从文件读取数据的
DatagramChannel:读写UDP网络协议数据
SocketChannel:读写TCP网络协议数据
ServerSocketChannel:可以监听TCP连接
---------------------------------------------------------------
1.java.nio.channels.FileChannel (抽象类):用于读、写文件的通道。
2.获取对象:
a.FileInputStream字节输入流类中
FileChannel getChannel() 返回与此文件输入流有关的唯一对象。
b.FileOutputStream字节输出流类中
FileChannel getChannel() 返回与此文件输出流有关的唯一对象。
3.成员方法:
int read(ByteBuffer dst) 读取多个字节存储到ByteBuffer中
int write(ByteBuffer src) 将ByteBuffer中的数据写入到文件中
MappedByteBuffer map(MapMode mode, long position, long size) 将此通道的文件区域直接映射到内存中。
参数:
FileChannel.MapMode mode:设置读写的模式
READ_ONLY:只读映射模式。
READ_WRITE:读取/写入映射模式。
PRIVATE:私有的镜像,写不会影响到存储节点
long position:文件中的位置,映射区域从此位置开始,一般都是从0开始
size - 要映射的区域大小,就是要复制文件的大小,单位字节
19.5高效读写
1.java.io.RandomAccessFile类,可以设置读、写模式的IO流类
2.构造方法:
RandomAccessFile(String name, String mode)
参数:
String name:要读取的数据源,或者写入的目的地
String mode:设置流的读写模式
"r":只读,必须是小写
"rw":读写,必须是小写
3.成员方法:
FileChannel getChannel() 返回与此文件关联的唯一 FileChannel 对象。
4.注意:
使用InputStream获得的Channel可以映射,使用map时只能指定为READ_ONLY模式,不能指定为READ_WRITE和PRIVATE,否则会抛出运行时异常!
使用OutputStream得到的Channel不可以映射!并且OutputStream的Channel也只能write不能read!
只有RandomAccessFile获取的Channel才能开启任意的这三种模式!
---------------------------------------------------------------
1.java.nio.MappedByteBuffer类
可以创建“直接缓存区”,实现磁盘和内存实时映射
最大可以映射:Integer.MAX_VALUE个字节(2G)左右。
2.成员方法:
byte get(int index) 获取缓冲区中指定索引处的字节
ByteBuffer put(int index, byte b) 把字节写入到指定的索引处
Day20【NIO、Selector、AIO】
20.1NIO(同步,非阻塞)
1.服务器:
java.nio.channels.ServerSocketChannel:针对面向流的侦听套接字的可
//获取对象,打开服务器套接字通道
static ServerSocketChannel open();
//给服务器绑定指定的端口号
ServerSocketChannel bind(SocketAddress local);
//监听客户端的请求
SocketChannel accept();
//设置服务器的阻塞模式 true:阻塞 false:非阻塞
SelectableChannel configureBlocking(boolean block);
//读取客户端发来的数据
int read(ByteBuffer dst);
//给客户端发送数据
int write(ByteBuffer src);
----------------------------------------------------------------
2.客户端:
java.nio.channels.SocketChannel:用于面向流的连接插座的可选通道。
//获取对象,打开套接字通道
static SocketChannel open();
//根据服务器的ip地址和端口号连接服务器,连接服务器成功/失败
boolean connect(SocketAddress remote);
//设置客户端的阻塞模式 true:阻塞 false:非阻塞
SelectableChannel configureBlocking(boolean block)
注意:
1.客户端设置为阻塞模式:connect方法会多次尝试连接服务器
连接成功connect方法返回true
连接服务器失败,会抛出连接异常
2.客户端设置为非阻塞模式:connect只会连接一次服务器
connect方法无论连接成功还是失败都返回false
所以客户端设置为非阻塞模式没有意义
但无论如何都不会抛出连接异常
20.2Selector(选择器)
java.nio.channels.Selector:SelectableChannel对象的多路复用器。
1.概念:
选择器Selector是NIO中的重要技术之一。它与SelectableChannel联合使用实现了非阻塞的多路复用。使用它可以节省CPU资源,提高程序的运行效率。
2.多路:
服务器端同时监听多个“端口”的情况。每个端口都要监听多个客户端的连接。使用了多路复用,只需要一个线程就可以处理多个通道,降低内存占用率,减少CPU切换时间,在高并发、高频段业务环境下有非常重要的优势。
3.实现:
//创建3个ServerSocketChannel服务器对象
//分别给3个ServerSocketChannel服务器对象绑定不同的端口号
//设置3个ServerSocketChannel对象为非阻塞模式(必须)
//获取Selector对象的方式:
static Selector open();
//使用服务器ServerSocketChannel对象中的方法register,把3个服务器通道注册到Selector选择器上
//Selector sel:传递要注册的选择器对象
//int ops:传递对应的事件
//SelectionKey.OP_ACCEPT 接受就绪,ServerSocketChannel在注册时只能使用此项
//SelectionKey.OP_CONNECT 连接就绪
//SelectionKey.OP_READ 读就绪
//SelectionKey.OP_WRITE 写就绪
SelectionKey register(Selector sel, int ops);
//获取已经注册的通道集合
abstract Set<SelectionKey> keys()
//获取连接了服务器的客户端个数,如果为0会阻塞
abstract int select()
//获取当前已连接的通道的集合
abstract Set<SelectionKey> selectedKeys()
//用迭代器遍历已连接的通道的集合
//获取创建此键的通道
abstract SelectableChannel channel()
//获取请求服务器的客户端通道对象
//读取数据
//用迭代器移除已读取已读取通道
20.3NIO2-AIO(异步、非阻塞)
1.概述:
JDK7新增的:AsynchronousIO:异步、非阻塞IO
主要在Java.nio.channels包下增加了下面四个异步通道:
AsynchronousSocketChannel
AsynchronousServerSocketChannel
AsynchronousFileChannel
AsynchronousDatagramChannel
2.创建AIO的服务器端:
java.nio.channels.AsynchronousServerSocketChannel:用于面向流的侦听套接字的异步通道。
//打开异步服务器套接字通道。
static AsynchronousServerSocketChannel open();
//给服务器绑定指定的端口号
AsynchronousServerSocketChannel bind(SocketAddress local);
//监听客户端的请求,默认就是非阻塞的方法
//A attachment:附件,可以传递null
//CompletionHandler<?> handler:事件处理的接口,用于处理accept方法监听到的事件
//CompletionHandler:也叫回调函数,客户端请求服务器之后,会自动执行CompletionHandler接口中的方法
void accept(A attachment, CompletionHandler<? super A> handler)
//java.nio.channels.CompletionHandler接口:用于消除异步I/O操作结果的处理程序。
//CompletionHandler handler 一个回调函数,客户端给服务器write发送数据之后,服务器会自动的执行这个回调函数
//创建匿名内部类,并重写两个方法
void completed(V result, A attachment) 客户端连服务器成功执行的方法
//非阻塞读取
void read(ByteBuffer dst, long timeout, TimeUnit unit, A attachment, CompletionHandler<?> handler)
//阻塞读取
Future<Integer> read(ByteBuffer dst)
//获取数据长度
V get() 等待计算完成,然后检索其结果。
void failed(Throwable exc, A attachment) 客户端连接服务器失败执行的方法
//非阻塞读取
//ByteBuffer dst - 要传输字节的缓冲区,用来存储读取到的数据
//long timeout - 完成I / O操作的最长时间
//TimeUnit unit - timeout参数的时间单位 (TimeUnit.SECONDS:秒)
//A attachment - 要附加到I / O操作的对象; 可以是null
-------------------------------------------------------------------
2.创建AIO的客户端:
java.nio.channels.AsynchronousSocketChannel:用于面向流的连接接口的异步通道。
//打开异步套接字通道
static AsynchronousSocketChannel open();
//连接服务器,传递服务器的IP地址和端口号
//connect是一个非阻塞的方法,不会等待方法运行完毕,连接服务器成功在执行下边的代码
//客户端连接服务器需要时间的,如果没有连接成功,就给服务器发送数据,会抛出异常
Future<Void> connect(SocketAddress remote)
//判断是否连接成功
//java.util.concurrent.Future<Void>接口
//true:连接服务器成功
//false:连接服务器正在进行中(还没有连接上服务器)
boolean isDone() 如果此任务完成,则返回 true 。
//给服务器发送数据
Future<Integer> write(ByteBuffer src)
//读取服务器发送的数据
Future<Integer> read(ByteBuffer dst)
------------------------------------------------------------------- 3.注意:
Future类表示异步计算的结果。 提供方法来检查计算是否完成,等待其完成,并检索计算结果。
V get() 等待计算完成,然后检索其结果。
V get(long timeout, TimeUnit unit) 如果需要等待最多在给定的时间计算完成,然后检索其结果(如果可用)。
boolean isDone() 如果此任务完成,则返回 true 。
Day21【反射、注解】
21.1类加载器
1.类的加载:
当程序在运行后,第一次用到某个类的时候,会将此类的class文件读取到内存,并将此类的所有信息存储到一个class对象中
2.class对象:
java.lang.Class类的对象,由Java类库提供,专门用来存储类的信息
3.类加载的时机:
1. 创建类的实例
2. 调用类的静态变量,或者为静态变量赋值
3. 调用类的静态方法
4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
5. 初始化某个类的子类
6. 直接使用java.exe命令来运行某个主类
4.类加载器:
概念:负责加载类的对象。将class文件(硬盘)加载到内存生成Class对象。
组成:
BootstrapClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载,\bin目录下
ExtClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。\lib\ext目录下的类
AppClassLoader 应用程序类加载器
负责加载我们自定义类的加载器
关系:
所有的类加载器都是 java.lang.ClassLoader 的子类,但其本身不是类,由c、c++编写
AppClassLoader extends ExtClassLoader extends BootstrapClassLoader extends ClassLoader
加载机制:全盘负责委托机制(双亲委派机制)
全盘负责:A类如果要使用B类(不存在),A类加载器必须负责加载B类。
委托机制:A类加载器如果要加载资源B,必须询问父类加载是否加载。
特点:
采用全盘负责委托机制保证一个class文件只会被加载一次,形成一个Class对象。
5.类加载器的获取:
1.使用Class类中的方法
ClassLoader getClassLoader() 返回该类的类加载器。
2.java.lang.ClassLoader类
ClassLoader getParent() 返回委托的父类加载器。
21.2Class类
1.获取class文件对象的方式:
class文件对象是由类加载器创建的,我们无权创建和销毁,我们只能获取class文件对象使用
1.使用Object类中的方法getClass获取
Class<?> getClass() 返回此 Object 的运行时类。
2.java会为每种数据类型都赋予一个class属性,这个class属性返回的就是class文件对象
3.可以使用Class类中的静态方法forName
static Class<?> forName(String className) 返回与带有给定字符串名的类或接口相关联的 Class 对象。
参数:
String className:全类名(包名+类名) 可以确定类的唯一性
4.注意:
class文件对象是唯一的,我们通过3种方式获取的都是同一个对象
2.常用方法:
String getSimpleName() 获取类名
String getName() 获取全类名(包名+类名)
21.3反射
1.概念:
反射是一种机制,利用该机制可以在程序运行过程中对类进行解剖并操作类中的所有成员(成员变量,成员方法,构造方法)。
2.前提:
类已经进入到内存,获取到该类字节码文件对象,就是Class对象。
3.好处:
提高代码的复用性,对于任意的一个类,都可以使用相同的方法进行解剖,开发环境和框架底层就大量的使用了反射技术。
-------------------------------------------------------------------
使用反射技术获取类中的构造方法,并使用获取到的构造方法实例化对象
1.获取构造方法
Constructor<?>[] getConstructors() 获取类的所有公共构造方法
Constructor<?>[] getDeclaredConstructors()获取类声明的所有构造方法(包括公共、保护、默认(包)访问和私有方法)
Constructor<T> getConstructor(Class<?>... parameterTypes) 获取指定公共构造方法
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取指定构造方法(包括公共、保护、默认(包)访问和私有方法)
参数:
Class<?>... parameterTypes:传递构造方法参数列表的class文件对象
2.使用获取到的构造方法Constructor类中的方法newInstance实例化(创建)对象
java.lang.reflect.Constructor<T>:描述构造方法的类
T newInstance(Object... initargs) 实例化对象的方法(创建对象)
参数:
Object... initargs:传递创建对象的实际参数
返回值:
T:返回创建好的对象,类型使用Object类型
注意:
私有构造方法是没有权限使用的,要使用会抛出IllegalAccessException:非法访问异常
解决:(不推荐)
使用Constructor的父类AccessibleObject类中方法解决
java.lang.reflect.AccessibleObject类
void setAccessible(boolean flag) 将此对象的 accessible 标志设置为指示的布尔值。
a.值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
b.值为 false 则指示反射的对象应该实施 Java 语言访问检查
----------------------------------------------------------------
使用反射技术获取构造方法并实例化对象的简化方式
1.java.lang.Class类:
T newInstance() 创建此 Class 对象所表示的类的一个新实例。
2.注意:
1.类中必须有空参数构造方法,创建对象使用的空参数是构造方法
2.空参数构造方法的修饰符不能private
21.4获取类的成员方法并运行
1.使用class文件对象中的方法获取类中(公共)的成员方法
Method[] getMethods() 获取本类|父类|接口继承成,所有的公共成员方法
Method[] getDeclaredMethods() 获取本类声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
Method getMethod(String name, Class<?>... parameterTypes) 获取指定公共成员方法,包括继承的。
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 获取指定已声明方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。。
参数:
String name:方法的名称
Class<?>... parameterTypes:方法参数列表的class文件对象
2.Method类中的方法
java.lang.reflect.Method:描述成员方法的类
String getName() 以 String 形式返回此 Method 对象表示的方法名称。
void setAccessible(true)设置暴力访问
Object invoke(Object obj, Object... args) 运行成员方法
参数:
obj:前面获取到的实例对象
args:方法参数,没有不写
3. 使用反射技术获取实现类所实现的所有接口(了解):学习动态代理的时候使用
Class类中方法:
Class<?>[] getInterfaces() 确定此对象所表示的类或接口实现的接口。
21.5反射之操作成员变量
每一个成员变量都是一个Field类的对象。
1.目的:
通过Field对象给对应的成员变量赋值和取值
2.Class类中与Field相关的方法:
Field getField(String name);根据成员变量名获得对应Field对象,只能获得public修饰
Field getDeclaredField(String name);根据成员变量名获得对应Field对象,包括public、protected、(默认)、private的
Field[] getFields();获得所有的成员变量对应的Field对象,只能获得public的
Field[] getDeclaredFields();获得所有的成员变量对应的Field对象,包括public、protected、(默认)、private的
3.Field对象常用方法:
void set(Object obj, Object value)
void setInt(Object obj, int i)
void setLong(Object obj, long l)
void setBoolean(Object obj, boolean z)
void setDouble(Object obj, double d)
Object get(Object obj)
int getInt(Object obj)
long getLong(Object obj)
boolean getBoolean(Object ob)
double getDouble(Object obj)
void setAccessible(true);// 暴力反射,设置为可以直接访问私有类型的属性。
Class getType(); // 获取属性的类型,返回Class对象。
21.6注解
1.概述:
注解是JDK1.5的新特性。
标记(注解)可以加在包,类,字段,方法,方法参数以及局部变量上。
注解是给编译器或JVM看的,编译器或JVM可以根据注解来完成对应的功能。
2.注解的作用:
使用javadoc生成帮助文档:里边可以包含注解@author和@version
编译检查:@Override @FunctionalInterface
框架的配置(框架=代码+配置):框架的时候讲
3.自定义注解:定义一个没有属性的注解
格式:
public @interface 注解名{ }
注意:
注解使用的也是.java文件,编译生成的也是.class文件
注解和类和接口和枚举都是同一个层次,都是一种数据类型
4.自定义注解:定义一个属性的注解
格式:
public @interface 注解名{
修饰符 数据类型 属性名();
修饰符 数据类型 属性名() default 默认值;
}
注意:
1.注解中没有成员变量,也没有成员方法
2.注解的属性,可以看成是抽象方法的格式,但是有默认值
3.注解的属性的修饰符固定使用public abstract;可以省略不写
4.注解属性的数据类型:
a.基本数据类型(4类8种)
b.引用数据类型:String类型,反射类型(Class),注解类型,枚举类型
c.以及以上所有类型的一维数组
5.定义注解,属性名叫value,可以包含其他的属性,但是必须有默认值
21.7使用自定义注解
1.注解可以使用的位置:
包上,类上|接口上,成员变量上,成员方法上,构造方法上,局部变量上,方法的参数上...
注意:
1.同一个位置,同名的注解只能使用一次
2.不同的位置,同名的注解可以使用多次
2.注解的使用格式:
1.没有属性的注解,通过@注解名可以直接使用
2.有属性的注解:必须使用键值对的方式,给注解中所有的属性都赋值之后,才能使用注解
格式:
@注解名(属性名=属性值,...属性名=属性值)
a.有默认值的属性,可以不用赋值,使用默认值
b.给多个属性赋值,中间要使用逗号分隔开
c.属性的数据类型是数组,属性的值需要使用{ }包裹起来,说明这一组值是一个数组属性的值
数组只有一个值,那么可以省略{ }
d.注解中只有一个属性,并且叫value;或者注解中有其他的属性,但是属性必须有默认值,那么我们在使用注解的时候,给属性赋值,可以省略属性名,直接写属性值
21.8元注解
概述:
1.Java官方提供的注解
2.用来定义注解的注解
3.任何官方提供的非元注解的定义都使用到了元注解。
1.@Target:
作用:
用来标识注解使用的位置,如果没有使用该注解标识,则自定义的注解可以使用在任意位置
属性:
ElementType[] value:只有一个属性,属性名叫value;使用的时候,可以省略属性名,直接写属性值
java.lang.annotation.ElementType:是一个枚举类型,枚举中的变量都是常量,可以通过枚举名.变量名直接使用
枚举中的常量:
TYPE,类,接口
FIELD, 成员变量
METHOD, 成员方法
PARAMETER, 方法参数
CONSTRUCTOR, 构造方法
LOCAL_VARIABLE, 局部变量
2.@Retention:
作用:用来标识注解的生命周期(有效范围,作用域)
属性:
RetentionPolicy value:只有一个属性,属性名叫value;使用的时候,可以省略属性名,直接写属性值
java.lang.annotation.RetentionPolicy:是一个枚举类型,枚举中的变量都是常量,可以通过枚举名.变量名直接使用
枚举中的常量:
SOURCE:注解只作用在源码阶段(.java),生成的字节码文件(.class)中不存在
CLASS:注解作用在源码阶段,字节码文件阶段,运行阶段(内存中)不存在,默认值
RUNTIME:注解作用在源码阶段,字节码文件阶段,运行阶段
21.9注解解析
1.获取注解的属性值,注解的解析底层使用的是反射技术:
注解作用在哪个成员上就会得该成员对应的对象来获得注解
比如注解作用成员方法,则要获得该成员方法对应的Method对象
比如注解作用在类上,则要该类的Class对象
比如注解作用在成员变量上,则要获得该成员变量对应的Field对象。
2.java.lang.reflect.AnnotatedElement接口:在接口中定义了注解解析的方法
3.AnnotatedElement接口的实现类:实现类都重写了接口中的方法,都可以使用,比如:AccessibleObject, Class, Constructor, Field, Method, Package
4.AnnotatedElement接口中的常用方法:
1.boolean isAnnotationPresent(Class annotationClass)
判断指定的对象上(Class,Method...),是否包含指定的注解
参数:
Class annotationClass:要判断的注解的class文件对象
返回值:boolean
有指定的注解,返回true
没有指定的注解,返回false
2.T getAnnotation(Class<T> annotationClass) 获取对象上(Class,Method...)指定的注解
参数:
Class<T> annotationClass:要获取的注解的class文件对象
返回值:
T:返回获取到的注解,获取的注解不存在返回null
3.Annotation[] getAnnotations() 获取对象上所有的公共注解
4.Annotation[] getDeclaredAnnotations() 获取对象上所有声明的注解,包含其他修饰符的
//转型为对应的注解类型,就可以使用注解名.属性名(),获取属性的值
Day22【XML、XML解析】
22.1介绍
1.介绍:
XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML,HTML文件也是XML文档
XML 被设计为具有自我描述性(就是易于阅读)
XML 是 W3C (万维网联盟)的推荐标准,1.0版本和1.1版本
2.与HTML的主要差异:
XML:
作用:存储数据,会获取出xml中存储的数据使用
可扩展的,标签的名称可以自定义
HTML:
作用:展示数据,给别人看的(页面)
标签的名称都是固定的
3.组成元素:
文档声明、元素、属性、注释、转义字符、字符区。文件扩展名必须为.xml
22.2语法
1.文档声名:
1.<?xml version="1.0" encoding="UTF-8" ?>
version:指定XML文档版本。必须属性,这里一般选择1.0;
enconding:指定当前文档的编码,可选属性,默认值是utf-8;
2.文档声明必须为<?xml开头,以?>结束
3.文档声明必须从文档的0行0列位置开始
2.元素element(元素就是标签)
1.格式:
<Person></Person>
<person/> 空元素 自闭和标签
2.元素是XML文档中最重要的组成部分
3.普通元素的结构由开始标签、元素体、结束标签组成。
4.元素体:元素体可以是元素,也可以是文本,
5.空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合
6.元素命名
1.区分大小写
2.不能使用空格,不能使用冒号
3.不建议以XML、xml、Xml开头
4.不能以数字开头
7.格式化良好的XML文档,有且仅有一个根元素。
3.属性attribute
1. 属性是元素的一部分,它必须出现在元素的开始标签中
2. 属性的定义格式:属性名=“属性值”,其中属性值必须使用单引或双引号括起来
3. 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
4. 属性名不能使用空格,不要使用冒号等特殊字符,且必须以字母开头
5. 属性不区分先后顺序,写在前边和写在后边的作用是一样的
4.注释:
<!- 注释内容 -->
注释的内容不会被xml解析器解析
快捷键:ctrl+shift+/ 和 ctrl+/
5.转义字符:
作用:
1.可以把部分普通的字符转义为有特殊含义的字符
2.可以把有特殊含义的字符转义为普通的字符
3.严格地讲,在 XML 中仅有字符 "<"和"&" 是非法的。省略号、引号和大于号是合法的,但是把它们替换为实体引用是个好的习惯。
常用的转义字符:
< <
> >
" "
' '
& &
6.CDATA字符区:
作用:
把大量标签以下的内容以文本的形式展示出来,可以用转义字符替换所有特殊字符来做到。而CDATA区域中写的任意的内容,都会以文本的形式解析。
所以如果需要大量使用转义字符的时候,使用CDATA字符区。
CDATA 部分不能包含字符串 "]]>"。也不允许嵌套的 CDATA 部分。
格式:
<![CDATA[
任意的内容,都是文本
]]>
22.3 XML文件的约束DTD
在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束。常见的xml约束:DTD、Schema。
1.DTD
文档类型定义(Document Type Definition)。DTD可以定义在XML文档中出现的元素、这些元素出现的次序、它们如何相互嵌套以及XML文档结构的其它详细信息。
2.使用:
1.声明dtd约束文档
2.根据约束文档的要求,写出根元素
3.在根元素中,根据提示写出其他的元素(写<就有提示我们可以写什么内容)
4.写<没有提示了,说明只能写文本了,不能写标签
3.文档声明:
声明dtd约束文档如何编写,一共有3种书写dtd文档的方式
1.内部DTD,在XML文档内部嵌入DTD,只对当前XML有效。
<!DOCTYPE beans [
... //具体的语法
]>
2.外部DTD—本地DTD,DTD文档在本地系统上,公司内部自己项目使用。
<!DOCTYPE beans SYSTEM "bean.dtd">
a.!DOCTYPE:是dtd约束文档的固定格式
b.beans:约束xml文档中的根元素想要使用dtd约束就必须叫beans
c.SYSTEM:系统,当前使用的dtd约束文档来源于本地的操作系统
d."bean.dtd":dtd约束文档所在的位置
3.外部DTD—公共DTD,DTD文档在网络上,一般都由框架提供。
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
a. !DOCTYPE:dtd约束文档声明的固定格式
b. Beans:根源元素的名称
c. PUBLIC:公共,dtd约束文档来源于互联网
d. "-//SPRING...":dtd约束文档的名称,一般由框架提供
e. "http://www....">:dtd约束文档在互联网上的位置
4.元素声明:
约束xml文档中的元素如何编写
<!ELEMENT 元素名 元素描述>
!ELEMENT:固定格式
元素名:自定义
元素描述包括:符号和数据类型
常见符号:
?:代表元素只能出现0次或者1次
+:代表元素至少出现1次
*:代表元素可以出现任意次
():一组元素 (a,b)* aaabbbb (a|b)* abba
|:选择关系 在多个中选择一个
,:顺序关系 a,b,c 元素书写顺序只能先写a,在写b,最后写c
常见类型:
#PCDATA 表示内容是文本,不能是子标签
EMPTY 即空元素,例如<hr/>
ANY 即任意类型
5.属性声明:
在约束文档中规定xml文档中的属性如何编写
<!ATTLIST 元素名
属性名 属性类型 约束
属性名 属性类型 约束
...
>
!ATTLIST:属性声明的固定写法
元素名:属性必须是给元素添加,所有必须先确定元素名
属性名:自定义
属性类型:ID、CDATA…
ID : ID类型的属性用来标识元素的唯一性(不能重复,必须有,只能以字母开头)
CDATA:文本类型,字符串
约束:
#REQUIRED:说明属性是必须的;required
#IMPLIED:说明属性是可选的;implied
#FIXED:代表属性为固定值,实现方式:book_info CDATA #FIXED "固定值"
22.4XML文件的约束schema
1.概述:
Schema 语言也可作为 XSD(XML Schema Definition)。
Schema 比DTD强大,是DTD代替者。
Schema 本身也是XML文档,但是Schema文档扩展名为xsd,而不是xml。
Schema 功能更强大,数据类型约束更完善。
Schema 支持命名空间
2.作用:
官方的schema约束文档:约束自定义的Schema文档如何编写
自定义的约束文档:约束xml文档如何编写(元素,属性)
3.使用:
1.在schema约束文档中有一个根元素的开始标签,复制到xml文档中
2.在根元素中,根据提示(写<出现提示要写的内容),写出其他的元素和属性
4.命名空间
1.每个Schema约束文档,都必须有一个名字,这个名字就是命名空间
要求:全球唯一,一般使用公司的域名+项目名称+...
2.在xml文档中想要使用Scheme约束文档,必须声明使用的是哪个Schema约束文档
a.默认声明:只能有一个
xmlns="default namespace"
xmlns="http://www.itcast.cn/bean"
b.显示声明:可以有多个
xmlns:别名1=”http://www.itcast.cn/bean”
xmlns:别名2="http://www.itcast.cn/bean"
3.想要使用Schema约束文档,必须确定约束文档的位置
a.先确定官方文档的位置
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
b.通过官方文档确定我们自己的Schema约束文档的位置
xsi:schemaLocation="{namespace} {location}"
4.使用
使用默认声明,直接写元素名称<bean></bean>
使用显示声明: 别名:元素名称
5.基本语法:
1. <element>声明元素(标签)
2.每个元素都必须确定类型
complexType:复杂类型
simple Type:简单类型,一般不用,大部分都是复杂类型
3.需要明确子标签的出场顺序
<choice>选择 ()
<sequence>顺序 ,
<all>任意
minOccurs:最少出现次数
maxOccurs:最大出现次数
unbounded:不限制(没有边)
4.<attribute>用于给元素声明属性
use:设置属性使用
optional:可选
required:必须
22.5XML解析
1.解析方式和解析器:
1.开发中比较常见的解析方式有三种:
1.DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象
a)优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
b)缺点:XML文档过大,可能出现内存溢出
2.SAX:是一种速度更快,更有效的方法。她逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都触发对应的事件。
a)优点:处理速度快,可以处理大文件
b)缺点:只能读,逐行后将释放资源,解析操作繁琐。
3.PULL:Android内置的XML解析方式,类似SAX。
2.解析器:
根据不同的解析方式提供具体实现。有的解析器操作过于繁琐,为了方便开发人员,又提供易于操作的解析开发包
3.常见的解析开发包
JAXP:sun公司提供支持DOM和SAX开发包
Dom4j:比较简单的的解析开发包
JDom:与Dom4j类似
Jsoup:功能强大DOM方式的XML解析开发包,尤其对HTML解析更加方便
2.使用dom4j解析xml文件:
SAXReader对象方法:
new SAXReader() 构造器
Document read(String url) 加载执行xml文档
Document对象方法:
Element getRootElement() 获得根元素
Element对象:
List elements([String ele]) 获得指定名称的所有子元素。可以不指定名称
Element element([String ele]) 获得指定名称第一个子元素。可以不指定名称
String getName() 获得当前元素的元素名
String attributeValue(String attrName) 获得指定属性名的属性值
String elementText(Sting ele) 获得指定名称子元素的文本值
String getText() 获得当前元素的文本内容
3.使用xpath和dom4j快读定位解析xml文件:
xpath是基于dom4j开发的,要使用xpath不仅仅的导入xpath的jar包,还需要使用dom4j的jar包
1.导入dom4j和xpath的jar包
2.创建dom4j核心类对象SAXReader
3.使用SAXReader对象中的方法read,读取xml文件到内存中,生成Doucment对象
4.使用Document对象中的方法selectNodes|selectSigleNode解析xml文件
List<Element> selectNodes("xpath表达式") 获取符合表达式的元素集合
Element selectSingleNode("xpath表达式") 获取符合表达式的唯一元素
4.xpath表达式常用查询形式
第一种查询形式:
//*: 所有元素
第二种查询形式
/AAA/DDD/BBB: 表示一层一层的,AAA下面 DDD下面的BBB
第三种查询形式
//BBB: 表示和这个名称相同,表示只要名称是BBB 都得到
第四种查询形式
//BBB[1]:表示第一个BBB元素
//BBB[2]:表示第二个BBB元素
...
//BBB[last()]:表示最后一个BBB元素
第五种查询形式
//BBB[@id]: 表示只要BBB元素上面有id属性 都得到
//BBB[@className]: 表示只要BBB元素上面有className属性 都得到
第六种查询形式
//BBB[@id='b1'] 表示元素名称是BBB,在BBB上面有id属性,并且id的属性值是b1
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-reYTstRc-1591629921372)(F:\资料\Java\笔记\img\1590302601869.png)]
Day23【设计模式】
23.1设计模式的分类
创建型-高效创建对象
简单工厂(SimpleFactory)
工厂方法(FactoryMethod)
抽象工厂(Abstract Factory)
创建者(Builder)
原型(Prototype)
单例(Singleton)
多例(Multiton)
结构型-对象的组成和依赖关系
外观(Facade)
适配器(Adapter)
代理(Proxy)
装饰者(Decorator)
桥(Bridge)
组合(Composite)
享元(Flyweight)
行为型-对象的行为
模板方法(Template Method)
观察者(Observer)
状态(State)
策略(Strategy)
责任链(Chain of Responsibility)
命令(Command)
访问者(Visitor)
调停者(Mediator)
备忘录(Memento)
迭代器(Iterator)
解释器(Interpreter)
23.2单例设计模式
1.宗旨:保证一个类只产生一个对象
2.饿汉式:
1.私有空参数构造方法,不让用户直接创建对象
2.定义一个私有的静态变量,并进行初始化赋值(创建一个对象给变量赋值)
3.定义一个公共的静态方法,返回Person对象
3.懒汉式:
1.私有空参数构造方法,不让用户直接创建对象
2.在类中定义一个私有的静态变量,不进行初始化赋值
3.定义一个公共的静态的成员方法,返回对象,保证只返回一个对象
4.用synchronized修饰静态方法,保证多线程安全。
23.2多例设计模式
1.概述:
多例模式,是一种常用的软件设计模式。通过多例模式可以保证系统中,应用该模式的类有固定数量的实例。多例类要自我创建并管理自己的实例,还要向外界提供获取本类实例的方法。
使某个类,在程序运行期间,只能产生固定的几个对象,不能多、也不能少。
2.步骤:
1. 创建一个类,将构造方法私有化。
2. 在类中定义该类被创建的总数量
3. 在类中定义存放类实例的list集合
4. 在类中提供静态代码块,在静态代码块中创建类的实例
5. 提供获取类实例的静态方法
23.3枚举
1.概念:
就是"多例设计模式:获取多个特定的对象"的一种简化写法
2.作用:
枚举通常可以用于做信息的分类,如性别,方向,季度等。
3.小结:
枚举类在第一行罗列若干个枚举对象。(多例)
第一行都是常量,存储的是枚举类的对象。
枚举是不能在外部创建对象的,枚举的构造器默认是私有的。
枚举通常用于做信息的标志和分类。
23.4工厂设计模式
1.简单工厂设计模式:
创建一个工厂类,在工厂类中定义一个生产对象的方法
我们要使用对象,不在自己创建对象了,使用工厂类的方法获取
好处:
可以给工厂类的方法传递不同的动物名称,生产不同的动物对象
解除耦合性,增强了扩展性
弊端:
胡乱传递一个动物的名称,不存在,会抛出空指针异常
解决:
可以使用工厂方法设计模式来解决;创建多个工厂,每个工厂生产特定的动物
2.工厂方法设计模式:
可以设计多个工厂,每个工厂生产不同的对象
猫工厂只生产猫,狗工厂只生产狗..
好处:
解决解决简单工厂设计模式的弊端,不让用户胡乱的传递参数了
弊端:
如果动物的种类过多,产生的工厂也有多个
23.5动态代理
1.概念:
创建代理对象,对A对象进行代理,对A的方法进行拦截
使用Proxy类生成代理人对象:
java.lang.reflect.Proxy:
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
参数:
ClassLoader loader:获取类加载器后,可以通过这个类型的加载器,在程序运行时,将生成的代理类加载到JVM即Java虚拟机中,以便运行时需要。A.getClass.getClassLoader()
Class<?>[] interfaces:传递被代理人实现的所有接口,获取被代理类的所有接口信息,以便于生成的代理类可以具有代理类接口中的所有方法。A.getClass.getInterfaces()
InvocationHandler h:生成代理人的接口,传递InvocationHandler接口的实现类对象。new 然后重写上面的invoke方法。
返回值:
Object:代理对象
2.java.lang.reflect.InvocationHandler接口
InvocationHandler 是代理实例的调用处理程序 实现的接口。
用来生产代理人对象的动态代理的接口
InvocatcionHandler接口中的方法:
Object invoke(Object proxy, Method method, Object[] args) 在代理实例上处理方法调用并返回结果。
作用:
使用invoke方法对被代理对象的方法进行拦截。
参数:
Object proxy:内部产生的代理人对象,没什么用
Method method:invoke方法要拦截的方法,方法内部使用反射技术获取到这些方法
Object[] args:拦截到的方法的参数
返回值:
Object:就是拦截到方法的返回值,不是newProxyInstance方法的返回值
23.6Lombok
lombok介绍:
通过增加一些“处理程序”,可以让java变得简洁、快速。
以注解形式来简化java代码,提高开发效率。
源码中没有getter和setter方法,但是在编译生成的字节码文件中有
常用注解:
@Getter和@Setter
作用:生成成员变量的get和set方法。
写在成员变量上,只对当前成员变量有效。
写在类上,对所有成员变量有效。
注意:静态成员变量无效。
@ToString:
作用:生成toString()方法。
该注解只能写在类上。
@NoArgsConstructor和@AllArgsConstructor
@NoArgsConstructor:无参数构造方法。
@AllArgsConstructor:满参数构造方法。该注解只能写在类上。
@EqualsAndHashCode
作用:生成hashCode()和equals()方法。
该注解只能写在类上。
@Data
作用: 生成setter/getter、equals、canEqual、hashCode、toString方法,
如为final属性,则不会为该属性生成setter方法。
该注解只能写在类上。
Day24【Java8新特性、正则表达式】
JDK新特性:
Lambda 表达式
默认方法
Stream API
方法引用
Base64
24.1方法引用
1.概念:
JDK1.8之后出现的新特性,用于简化Lambda表达式
当一些内容已经存在了,我们就可以使用方法引用,直接引用这些已经存在的内容
::方法引用的运算符
2.对象名--引用成员方法
格式:
对象名::成员方法,参数
当对象和成员方法都是已经存在的时候,就可以使用对象名来引用成员方法
3. 类名--引用静态方法
格式:
类名::静态成员方法,参数
如果类和静态成员方法已经存在的,那么就可以使用类名直接引用静态成员方法
4.类--构造引用
格式:
构造方法::new,参数
如果类中的构造方法是已经存在的,使用构造方法直接引用new关键字创建对象
5.数组--构造引用
格式:
数据类型[]::new,参数
24.2Base64
1.概述:
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
在Java 8中,Base64编码已经成为Java类库的标准。
java.util.Base64工具类
该类仅由用于获得Base64编码方案的编码器和解码器的静态方法组成。
作用:
使用Base64里边的编码器对数据进行编码(加密)
使用Base64里边的解码器对数据进行解码(解密)
静态方法:
static Base64.Encoder getEncoder() 获取加密器(编码器)
static Base64.Decoder getDecoder() 获取解密器(解码器)
java.util.Base64.Encoder:是Base64的内部类,用于对数据进行加密
成员方法:
String encodeToString(byte[] src) 使用Base64编码方案将指定的字节数组编码为字符串。
java.util.Base64.Decoder:是Base64的内部类,用于对数据进行解密
成员方法:
byte[] decode(String src) 使用Base64编码方案将Base64编码的字符串解码为新分配的字节数组。
24.3正则表达式
正则表达式:
就是一个包含了某些规则的字符串
用来对其他的字符串进行校验,校验其他的字符串是否满足正则表达式的规则
java.util.regex.Pattern:正则表达式的编译表示形式。 定义了正则表达式的一些规则
String类中方法:
boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。
String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
String replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
1.字符类
[]表示一个区间,区间的范围可以自己定义
语法示例:
1. [abc]:代表a或者b,或者c字符中的一个。
2. [^abc]:代表除a,b,c以外的任何字符。
3. [a-z]:代表a-z的所有小写字符中的一个。
4. [A-Z]:代表A-Z的所有大写字符中的一个。
5. [0-9]:代表0-9之间的某一个数字字符。
6. [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
7. [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符
2.逻辑运算符:
语法示例:
1. &&:并且 多个条件同时满足
2. || :或者 满足其中一个条件即可
3.预定义字符:
\本身就是转义字符,写正则表达式的时候,必须写\\,把有特殊含义的\转义为一个普通的\使用
语法示例:
1. "." : 匹配任何字符。(重点)
2. "\\d":任何数字[0-9]的简写 (重点)
3. "\\D":任何非数字[^0-9]的简写
4. "\\s": 空白字符(空格):[ \t\n\x0B\f\r] 的简写
5. "\\S": 非空白字符:[^\s] 的简写
6. "\\w":单词字符:[a-zA-Z_0-9]的简写(重点)
7. "\\W":非单词字符:[^\w]
4.数量词:
语法示例:
1. X? : 0次或1次
2. X+ : 1次或多次
3. X* : 0次到多次 任意次
4. X{n} : 恰好n次 X==n次
5. X{n,} : 至少n次 X>=n次
6. X{n,m}: n到m次(n和m都是包含的) n=<X<=m
5.分组括号( )
格式:
对象名::成员方法,参数
当对象和成员方法都是已经存在的时候,就可以使用对象名来引用成员方法
3. 类名–引用静态方法
格式:
类名::静态成员方法,参数
如果类和静态成员方法已经存在的,那么就可以使用类名直接引用静态成员方法
4.类–构造引用
格式:
构造方法::new,参数
如果类中的构造方法是已经存在的,使用构造方法直接引用new关键字创建对象
5.数组–构造引用
格式:
数据类型[]::new,参数
## 24.2Base64
```java
1.概述:
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
在Java 8中,Base64编码已经成为Java类库的标准。
java.util.Base64工具类
该类仅由用于获得Base64编码方案的编码器和解码器的静态方法组成。
作用:
使用Base64里边的编码器对数据进行编码(加密)
使用Base64里边的解码器对数据进行解码(解密)
静态方法:
static Base64.Encoder getEncoder() 获取加密器(编码器)
static Base64.Decoder getDecoder() 获取解密器(解码器)
java.util.Base64.Encoder:是Base64的内部类,用于对数据进行加密
成员方法:
String encodeToString(byte[] src) 使用Base64编码方案将指定的字节数组编码为字符串。
java.util.Base64.Decoder:是Base64的内部类,用于对数据进行解密
成员方法:
byte[] decode(String src) 使用Base64编码方案将Base64编码的字符串解码为新分配的字节数组。
24.3正则表达式
正则表达式:
就是一个包含了某些规则的字符串
用来对其他的字符串进行校验,校验其他的字符串是否满足正则表达式的规则
java.util.regex.Pattern:正则表达式的编译表示形式。 定义了正则表达式的一些规则
String类中方法:
boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。
String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
String replaceAll(String regex, String replacement) 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
1.字符类
[]表示一个区间,区间的范围可以自己定义
语法示例:
1. [abc]:代表a或者b,或者c字符中的一个。
2. [^abc]:代表除a,b,c以外的任何字符。
3. [a-z]:代表a-z的所有小写字符中的一个。
4. [A-Z]:代表A-Z的所有大写字符中的一个。
5. [0-9]:代表0-9之间的某一个数字字符。
6. [a-zA-Z0-9]:代表a-z或者A-Z或者0-9之间的任意一个字符。
7. [a-dm-p]:a 到 d 或 m 到 p之间的任意一个字符
2.逻辑运算符:
语法示例:
1. &&:并且 多个条件同时满足
2. || :或者 满足其中一个条件即可
3.预定义字符:
\本身就是转义字符,写正则表达式的时候,必须写\\,把有特殊含义的\转义为一个普通的\使用
语法示例:
1. "." : 匹配任何字符。(重点)
2. "\\d":任何数字[0-9]的简写 (重点)
3. "\\D":任何非数字[^0-9]的简写
4. "\\s": 空白字符(空格):[ \t\n\x0B\f\r] 的简写
5. "\\S": 非空白字符:[^\s] 的简写
6. "\\w":单词字符:[a-zA-Z_0-9]的简写(重点)
7. "\\W":非单词字符:[^\w]
4.数量词:
语法示例:
1. X? : 0次或1次
2. X+ : 1次或多次
3. X* : 0次到多次 任意次
4. X{n} : 恰好n次 X==n次
5. X{n,} : 至少n次 X>=n次
6. X{n,m}: n到m次(n和m都是包含的) n=<X<=m
5.分组括号( )