Java 应用开发

ObjectKaz Lv4

Java 介绍

三个不同的版本

  • Java SE:桌面应用程序的开发
  • Java EE:网页程序的开发
  • Java ME:嵌入式系统程序的开发

Java SE 就是标准版,包含标准的 JVM 和标准库

Java EE 是企业版,它只是在 Java SE 的基础上加上了大量的 API 和库,以便方便开发 Web 应用、数据库、消息服务等,Java EE 的应用使用的虚拟机和 Java SE 完全相同。
Java ME 就和 Java SE 不同,它是一个针对嵌入式设备的“瘦身版”,Java SE 的标准库无法在 Java ME 上使用,Java ME 的虚拟机也是“瘦身版”。

Java 的特点

  • 面向对象
  • 分布性
  • 高性能
  • 动态
  • 健壮性
  • 解释性:运行 Java 程序需要解释器
  • 安全性:删除了指针,避免非法内存操作
  • 可移植性:与体系结构无关

Java 运行环境

  1. JDK(Java Development Kit) 是针对 Java 开发员的产品,是整个 Java 的核心,包括 Java 运行环境 JRE、Java 工具和 Java 基础类库。

  2. JRE(Java Runtime Environment) 是运行 Java 程序所必需的环境的集合,包含 JVM 标准实现及 Java 核心类库。

  3. JVM(Java Virtual Machine) 是 Java 虚拟机的缩写,是整个 Java 实现跨平台的最核心的部分,能够运行以 Java 语言编写的软件程序。

三者之间的关系:

  • JDK=JRE+编译器+调试器+…
  • JRE=JVM+运行时类库

Java 基础

标识符

  • 组成:字母、数字、下划线、$
  • 开头:字母、下划线、$
  • 区分大小写
  • 不能和关键字重名

变量

  • 局部变量、成员变量

  • 类外面不能有变量的声明

数据类型

基本数据类型

整数类型

  1. 各个类型占用的空间:

    • byte:8 位
    • short:16 位
    • int:32 位
    • long:64 位(结尾加上 L 或 l)
  2. 进制

    • 十进制
    • 八进制:必须以 0 开头
    • 十六进制:必须以 0x 开头

浮点数类型

  • float:单精度浮点类型,32 位,结尾必须加 F 或 f
  • double:双精度浮点类型,64 位

字符类型:char

布尔类型:boolean

引用数据类型

字符串、对象、类、接口、数组等

变量和常量

  1. 常量的声明 final
  2. 局部变量初始化之后才能使用
  3. 静态成员变量有默认值

流程语句

  1. if 语句
  2. switch 语句:整数、字符型
  3. forwhiledo-while 循环
  4. foreach 语句
1
2
3
4
for(元素变量 x : 遍历对象 obj)
{
// 对当前元素x进行操作
}

增强 for 循环:

  1. 增强 for 循环必须有被遍历的目标(如集合或数组)。这个目标需要实现可迭代(Iterable)的接口。
  2. 普通 for 循环遍历数组的时候需要索引。
  3. 增强 for 循环不能获取下标,所以遍历数组时最好使用普通 for 循环。

数组

  1. 初始化
1
2
int  arr[]=new int[]{1,2,3,5,25};
int arr2[]={34,23,12,6}; // 省略 new

整型数组如果未初始化,则每个元素会执行 隐式初始化

  1. 多维数组
1
2
3
4
5
6
7
// 方式一:统一数组长度(静态)
a=new int[2][4];

// 方式二:分别定义数组长度(动态)
a=new int[2][];
a[0]=new int[2];
a[1]=new int[3];

【理解】锯齿数组:二维数组中,每个一维数组的长度可以不一样。

  1. 数组长度 arr.length

  2. 数组常用操作(了解)

操作描述
Arrays.fill(int[] a, int value)
fill(int[] a, int fromIndex, int toIndex, int value)
数组填充元素,参数 toIndex 对应位置的元素不包括在内
Arrays.sort(int[] a)数组排序。整型比大小,字符串按字典序进行排序
copyOf(int[]arr, int Len)
copyOfRange(int[]arr, int fromIndex, int toIndex
复制数组(第一个是复制指定长度,第二个是复制指定范围)

字符串

概述

  1. 引用类型
  2. 不可变的字符序列,不能修改其中的字符,每次操作产生新的字符串

常见操作

  1. 字符串连接:使用 + 号,可连接字符串与其它任何类型连接,其它类型数据会自动转换为字符串类型

Java 中的字符串不能分开在两行中写,如果字符串太长,可用“+”号将两行字符串连接起来

  1. 获取某一个字符:s.charAt(int index)
  2. 字符串长度:s.length() 注意有括号
  3. 获取子串的位置:str.indexOf(substr)str.lastindexOf(substr)

如果 lastIndexOf()方法中的参数是空字符串””,则返回的结果与调用该字符串的 length()方法的返回结果相同

  1. 清理开头和末尾的空格 s.trim()

  2. 判断相等: s.equals(xxx) s.equalsIgnoreCase()

== 比较的是字符串的内存位置,而不是它的值

  1. 判断开头结尾: str.startsWith(String prefix)str.endsWith(String suffix);

  2. 大小写转换:

    • str.toLowerCase():字符串全部转换为小写
    • str.toUpperCase():字符串全部转换为大写

合并和分割

  1. 分割成字符串数组:str.split(String sign)str.split(String sign, int limit)

如果想定义多个分割符,可使用符号“|”,例如,“,|=”表示分割符分别为“,”与“=”

  1. 合并字符串数组:String.join(String delimiter,String[] arr)

格式化

  1. 格式化字符串:String.format(str,arg1,arg2,...)
1
System.out.println(String.format("Hi %s, your score is %.2f!", "Bob", 59.5));
  • %s:显示字符串;
  • %d:显示整数;
  • %x:显示十六进制整数;
  • %f:显示浮点数。

转换

目标类型字符串->目标类型目标类型->字符串
IntegerInteger.parseIntInteger.toString

其他类型同理。

字符串生成器

概述

  1. 使用 String 类的场景:在字符串不经常变化的场景中可以使用 String 类,例如常量的声明、少量的变量运算。

  2. 使用 StringBuffer 类的场景:在频繁进行字符串运算(如拼接、替换、删除等),并且运行在多线程环境中,则可以考虑使用 StringBuffer,例如 XML 解析、HTTP 参数解析和封装。

  3. 使用 StringBuilder 类的场景:在频繁进行字符串运算(如拼接、替换、和删除等),并且运行在单线程的环境中,则可以考虑使用 StringBuilder,如 SQL 语句的拼装、JSON 封装等。

  4. StringBuilder 提供了与 StringBuffer 兼容的 API

  5. StringBuilder 线程不安全,StringBuffer 线程安全

操作

  1. 追加 builder.append(xxx) xxx 可以是任意类型
  2. 插入 builder.insert(int offset, String str)
  3. 删除 builder.delete(int start, int end)

如果 start 与 end 的位置相同,字符串生成器的值不变,按原样输出

  1. 转换成字符串:builder.toString()

异常

异常的分类

  • Error:称为错误,由 Java 虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,程序对其不做处理。
  • Exception:所以异常类的父类,其子类对应了各种各样可能出现的异常事件,一般需要用户显式的声明或捕获。
  • Runtime Exception:一类特殊的异常,如被 0 除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显式的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)

常用关键字

  • try :里面是可能出现异常的语句或者代码块。后面可以跟一个或多个 catch 代码段。出现异常,终止 try 代码段的执行,根据错误的类型找到对 应的 catch 执行。
  • catch 捕获异常 ,进行相应处理
  • finally :无论是否产生异常都会执行。一般用于资源的清除工作,比如 io 流的关闭, jdbc 的驱动关闭。
  • throws :用于方法声明时抛出异常
  • throw :用于实际手动抛出异常。

集合

继承关系:

Set 常用操作

  1. new HashSet<>()
  2. 插入元素 set.add(obj)
  3. 删除元素 set.remove(obj)
  4. 是否存在 set.contains(obj)
  5. 清空 set.clear()
  6. 取大小 set.size()
  7. 是否为空 set.isEmpty()

ArrayList 常用操作

  1. 创建 new ArrayList<>()
  2. 访问元素 list.get(index)
  3. 插入元素 list.add(obj) list.add(index,obj)
  4. 删除元素 list.remove(index) list.remove(obj)
  5. 是否存在 list.contains(obj)
  6. 清空 list.clear()
  7. 取大小 list.size()
  8. 是否为空 list.isEmpty()

LinkedList 常用操作

  1. 创建 new LinkedList<>()
  2. 访问元素 list.get(index) list.getFirst() list.getLast()
  3. 插入元素 list.add(obj) list.add(index,obj) list.addFirst(obj) list.addLast(obj)
  4. 删除元素 list.remove(index) list.remove(obj)
  5. 是否存在 list.contains(obj)
  6. 清空 list.clear()
  7. 取大小 list.size()
  8. 是否为空 list.isEmpty()

HashMap 常用操作

  1. 创建 new HashMap<Integer,Integer>()
  2. 插入元素 map.put(key,value)
  3. 删除元素 map.remove()
  4. 是否存在 map.containsKey(key) map.containsValue(value)
  5. 清空 map.clear()
  6. 取大小 map.size()
  7. 是否为空 map.isEmpty()

Java 面向对象

特性

  1. 封装
  2. 继承
  3. 多态

基本概念

  1. 主方法:public static void main(String[] args)
  2. 成员修饰符:publicprivateprotected
成员修饰符类内包内子类任意位置
public
protected
默认
private
  1. 类的修饰符:public(包外可访问)、默认(仅包内可访问)

没有修饰符,则只有一个包中的类可以调用这个类的成员变量或成员方法

  1. this 关键字:访问类自身的内容

访问对象的属性可以不使用 this,除非遇到了同名覆盖的问题

  1. super关键字:访问基类的内容
  2. static 关键字:定义静态成员
    • 静态成员在第一次使用时被初始化
    • 静态成员函数可以被实例或者类访问,不能访问非静态成员

  1. 在文件开头使用 package 关键字声明包名,可以使用 . 进行分隔。
  2. 没有定义包名的 class 在默认包下,容易出现名字冲突。
  3. 包和包之间没有父子关系。如 java.utiljava.util.zip 是不同的包,两者没有任何继承关系。
  4. 包作用域:位于同一个包的类,可以访问包作用域的字段和方法。没有使用成员修饰符的成员,默认是包作用域。
  5. import 语句:用来其他导入包中的类。(如果不 import ,则访问类需要带包名)
    • 可以使用* 把当前包下的所有类导入。
    • import static 用于导入一个类的静态字段和静态方法。

重写

概念

  1. 在子类中可以根据需要对从基类中继承来的方法进行重写。
  2. 重写方法必须和被重写方法具有相同方法名称、参数列表和返回类型。
  3. 重写方法不能使用比被重写方法更严格的访问权限。
  4. 可以在要重写的方法上面加上 @Override 关键字,这样编译器可以帮你检查重写的方法是否正确。但这不是必须的,可以不写。
  5. 带有 final 关键字的方法不能被重写。

重写和重载的区别

  1. 方法的重载是指在一个类中出现多个方法名相同,但参数个数或类型不同的方法

  2. 重载的方法之间并不一定必须有联系,但是为了提高程序的可读性,一般只重载功能相似的方法。在进行方法的重载时,方法返回值的类型不能作为区分方法的标志。

特殊的成员函数

  1. finialize 成员函数(相当于析构函数):当垃圾收集器销毁(System.gc())对象时调用。
  2. equals 方法:(默认是比较内存地址是否相等)用于比较两个对象是否相等。
  3. toString 方法:返回该对象的字符串表示,默认是 [object Object]
  4. hashCode 方法:用于返回一个对象的哈希码。(用于哈希表)

派生类

  1. 如果子类有构造函数,且基类没有无参构造函数,则需要通过构造函数调用 super 方法,执行基类的构造函数。
  2. super函数必须是子类构造函数的第一条语句。
  3. Object 是所有 java 类的根基类。
  4. 带有 final 关键字的类不能被继承。

多态

  1. 要有继承
  2. 要有重写
  3. 基类引用指向派生类对象

抽象类和抽象方法

  1. 用 abstract 关键字来修饰一个类时,这个类叫做抽象类。
  2. 用 abstract 来修饰一个方法时,该方法叫做抽象方法。抽象方法不能使用 privatestatic 关键字修饰。
  3. 含有抽象方法的类必须被声明为抽象类,抽象类必须被继承,抽象方法必须被重写。
  4. 抽象类不能被实例化。抽象方法只需声明,而不需实现。
1
2
3
abstract class Test {
abstract void test();
}

接口

  1. 接口 interface 是抽象方法和常量值的定义的集合。
  2. 接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有变量和方法的实现。
  3. 接口和类的关系:
    • 多个无关类可以实现(implements 关键字)同一个接口。
    • 一个类可以实现(implements 关键字)多个无关的接口。
  4. 接口和接口的关系:
    • 接口实现(implements 关键字)多个接口
    • 接口可以继承(extends 关键字)多个接口

Java Web

概述

B/S 架构和 C/S 架构

C/S 架构(客户端-服务器)

优点:

  1. 安全性好:C/S 程序部署在特定的客户端,系统的操作用户通常比较确定
  2. 效率高:客户端和服务器直接相连,数据传输比较快,系统运行效率比较高
  3. 个性化:可以根据需要对不同客户端上的程序进行界面和功能方面的定制,满足客户的个性化要求
  4. 稳定性强:C/S 结构比较稳定,有较强的事务处理能力,可以实现较复杂的业务逻辑

缺点:

  1. 适用面窄:C/S 程序通常部署于局域网中,能够使用的业务场景较少,适用范围较窄
  2. 用户群固定:C/S 架构系统需要安装客户端程序才可以使用,不适合面向不可知的用户
  3. 维护成本高:C/S 程序升级时需要对所有客户端程序进行升级,维护成本较高

B/S 架构(浏览器-服务器)

优点:

  1. 客户端免安装
  2. 交互性强
  3. 维护成本低

缺点:

  1. 浏览器兼容性差
  2. 效率低
  3. 安全风险高
  4. 实时性差

三层架构

  • 表示层(UI,User Interface Layer):与用户交互
  • 业务层(BLLL,Business Logic Layer):对业务逻辑和功能的操作
  • 数据访问层(DAL,Data Access Layer):对数据操作的封装
graph LR
USER(用户)-->UI[表示层]-->BLL[业务层]-->DAL[数据访问层]-->DB[(数据库)]
DB-->DAL-->BLL-->UI-->USER

HTTP 请求响应机制

  1. 建立 TCP 连接
  2. 浏览器发送请求
  3. 服务器响应数据
  4. 断开 TCP 连接

HTTP 常见状态码

  • 200:OK
  • 301:Moved Permanently
  • 302/307:Move Temporarily
  • 304:Not Modified
  • 400:Bad Request
  • 404:Not Found
  • 500:Internal Server Error

Tomcat

  1. Tomcat 服务器是一个开源的轻量级 Web 应用服务器,在中小型系统和并发量小的场合下被普遍使用,是开发和调试 Servlet、JSP 程序的首选。
  2. Tomcat 的默认端口号是 8080
服务器默认端口
Tomcat8080
IIS80
Oracle1521
SQL Server1433
Exchange25

Servlet

概念

  1. Servlet 是 Java Servlet 的简称,是用 Java 语言编写的服务器端程序,主要用于接收和响应客户端的 http 请求,使得客户端可以交互式地浏览和修改服务器端数据,生成动态 Web。

功能:

  1. 读取客户端(浏览器)发送的显式的数据
  2. 读取客户端(浏览器)发送的隐式的 HTTP 请求数据处理数据并生成结果
  3. 发送显式的数据(即文档)到客户端(浏览器)发送隐式的 HTTP 响应到客户端(浏览器)

生命周期

  1. Servlet 通过调用 init()方法进行初始化
  2. Servlet 调用 service() 方法来处理客户端的请求,并在适当的时候调用 doGetdoPost等方法处理请求
  3. Servlet 通过调用 destroy() 方法终止(结束)
  4. 由 JVM 的垃圾回收器对 Servlet进行垃圾回收
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 继承 HTTPServlet类
public class TestMyServlet extends HttpServlet {
@Override
public void init() throws ServletException {
super.init();
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.service(req, resp);
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

}

@Override
public void destroy() {
super.destroy();
}
}

操作步骤

  1. 创建 WEB 项目
  2. 创建 Servlet
  3. 注册 Servlet

定义 Servlet

1
2
3
4
<servlet>
<servlet-name><!--名称--></servlet-name>
<servlet-class><!--对应的类--></servlet-class>
</servlet>

Servlet 访问方式的声明

1
2
3
4
<servlet-mapping>
<servlet-name><!--名称--></servlet-name>
<url-pattern><!--访问路径--></url-pattern>
</servlet-mapping>
  1. 部署
  2. 访问 Servlet

请求与响应控制

s

请求转发

  1. 服务器内部转发
1
request.getRequestDispatcher(url).forward(request,response);
  1. 客户端转发(客户端发送 302 状态码,并跳转)
1
response.sendRedirect(url)

HttpServletRequset 常用方法

  • getContextPath():返回请求的上下文路径

  • getCookies():返回请求中发送的所有 Cookie 对象,返回值是 Cookie 数组

  • getMethod():返回请求所使用的 HTTP 类型,如 GET、POST

  • getQueryString():返回请求中参数的字符串形式,“MyServlet?username=mr”

  • getRequestURI():返回主机名(不含)到请求参数之间部分的字符串形式

  • getRequestURL():返回请求的 URL,不包括请求的参数,返回类型为 StringBuffer

  • getServletPath():返回 Servlet 路径的字符串

  • getSession():返回与请求关联的 HttpSession 对象

  • Object getParameter(name) 获取请求参数(例如,form 表单中的数据)

HttpServletResponse 常用方法

  • addCookie():向客户端写入 Cookie 信息

  • sendError():发送错误响应到客户端

  • sendRedirect():重定向

  • getWriter() 获取一个流对象,可以使用 println 方法。

数据存储

  1. 在客户端存储用户的状态信息,发送请求时会自动把这个信息带回到服务器
  2. 获取 Cookie 数组:request.getCookies();
  3. 创建 Cookie 类:new Cookie(String name,String value);
  4. 名称:c.getName()c.setName()
  5. 值:c.getValue()c.setValue()
  6. 发送 Cookie:response.addCookie(Cookie c)

Session

  1. 用来在服务端保存用户信息
  2. 其中,SessionID 一般通过 Cookie 的形式保存在客户端
  3. 获取属性:Object session.getAttribute(String n)
  4. 设置属性:session.setAttribute(String n,Object v)
  5. 移除属性:session.removeAttribute(String n
  6. 获取 ID:String session.getId()
  7. 失效:session.invalidate()

过滤器

用于在 Servlet 处理之前,处理请求和响应。

配置

定义 Filter

1
2
3
4
<filter>
<filter-name><!--名称--></filter-name>
<filter-class><!--对应的类--></filter-class>
</filter>

Filter 拦截 URL 的声明

1
2
3
4
<filter-mapping>
<filter-name><!--名称--></filter-name>
<url-pattern><!--访问路径--></url-pattern>
</filt-mapping>

/* 表示拦截所有路径

生命周期

  1. init:Filter 的创建和销毁由 WEB 服务器负责。web 应用程序启动时,web 服务器将创建 Filter 的实例对象,并调用其 init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(注: filter对象只会创建一次,init 方法也只会执行一次。)开发人员通过 init 方法的参数,可获得代表当前 filter 配置信息的 FilterConfig 对象。
  2. destroy:在 Web 容器卸载 Filter 对象之前被调用。该方法在 Filter 的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TestFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
}

public void destroy() {
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
// 把请求转发给下一个过滤器
chain.doFilter(request, response);
// 也可以直接做响应,这时候请求和响应不会转发到下一个 Filter或者Servlet
((HttpServletResponse)response).sendError(403,"你没有权限访问这个页面");
}
}

监听器

概念

监听器就是一个实现特定接口的普通 java 程序,这个程序专门用于监听一个 java 对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。

在 Servlet 规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletConext, HttpSessionServletRequest 这三个域对象。

Servlet 规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型:

  • 监听三个域对象创建和销毁的事件监听器
  • 监听域对象中属性的增加和册除的事件监听器 session.setAttribute("a")
  • 监听绑定到 HttpSession域中的某个对象的状态的事件监听器。

优先级:Listern->Filter->Servlet

JDBC

Prepared Statement 和 Statement 的区别

  1. PreparedStatement 在执行 sql 语句时可以包含动态参数占位符“?”,在执行时可以为占位符“?”动态设置参数值,而 Statement 不支持占位符“?”替换变量,只能在 sql 中拼接参数。所以在代码的可读性以及可维护性上,PreparedStatement 接口大大提高了代码的可读性和可维护性。
  2. PreparedStatement 会预编译 sql 语句,因此当多次执行时,只需 DBMS 运行 sql 语句,而不必再编译。而 Statement 没有预处理,每次都要重新编译,所以当多次执行这条 sql 语句时,PreparedStatement 效率会大大的提高。
  3. PreparedStatement 可以防止 sql 注入,极大地提高了安全性
  • 标题: Java 应用开发
  • 作者: ObjectKaz
  • 创建于: 2021-12-29 13:48:47
  • 更新于: 2021-12-30 05:21:11
  • 链接: https://www.objectkaz.cn/be0695301adf.html
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。