Java学习资料

Java

java基础概述

JDK > JRE >JVM

JDK

JDK是 Java 语言的软件开发工具包(Java Development Kit),主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具 SE(JavaSE),standard edition,标准版 EE(JavaEE),enterprise edition,企业版 -> Jakarta EE ME(J2ME),micro edition,主要用于移动设备、嵌入式设备上的java应用程序

JRE

JRE是Java Runtime Environment缩写,指Java运行环境,是Sun的产品。运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库

JVM

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的

标识符

变量命名,数字,字母,下划线,美元符号,不以数字开头

常量名:所有字母都大写。多单词时每个单词用下划线连接

方法命名,首字母必须小写,中间所有首字母大写

类命名,首字母必须大写,其他单词首字母也大写

Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符,凡是自己可以起名字的地方都叫标识符。

定义合法标识符规则:

  1. 由26个英文字母大小写,数字:0-9 ,_或 $ 组成
  2. 数字不可以开头。
  3. 不可以使用关键字和保留字,但能包含关键字和保留字。
  4. Java中严格区分大小写,长度无限制。
  5. 标识符不能包含空格。

部分关键字

访问权限修饰符:

  1. private 私有,当前类

  2. protected 保护,同一个包

  3. public 公共 default : 即缺省,什么也不写,在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。 private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类),最严格 public : 对所有类可见。使用对象:类、接口、变量、方法 protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

声明为 private 的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private。变量只能通过类中公共的 getter 方法被外部类访问。

private 访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据

父类中声明为 public 的方法在子类中也必须为 public。 ​父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。 ​父类中声明为 private 的方法,不能够被继承

定义类,方法,变量修饰符:

  1. abstract 抽象方法,表明类或者成员方法具有抽象属性
  2. final 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,修饰的变量为常量,是不可修改的。
  3. static 静态 静态变量:(类名.静态变量) static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量(全局)。 局部变量不能被声明为 static 变量。(跟类同级) 静态方法:(类名.静态方法) static 关键字用来声明独立于对象的静态方法。 静态方法不能使用类的非静态变量,在静态方法里不能直接访问非静态成员变量 静态方法从参数列表得到数据,然后计算这些数据 静态代码块 static{}: 当加载类时,只会执行一次,只能包含静态成员(例如JDBC里的加载驱动可以放入static{ }执行)
  4. synchronized 表明一段代码需要同步执行,synchronized 和 volatile 修饰符,主要用于线程的编程。

定义类之间:

1.extends 继承

2.implements 表明一个类实现了给定的接口

变量

按被声明的位置划分:

  1. 成员变量:方法外部、类的内部定义的变量
  2. 局部变量:方法或语句块内部定义的变量
    注意:类外面(类对应的大括号外面)不能有变量的声明

按所属的数据类型划分:

  1. 基本数据类型变量
  2. 引用数据类型变量

数据类型

基本类型(8个):

  1. 数值型

    • 整数:byte(1字节),short(2字节),int(4字节),long(8字节),初始值:0,

    • 浮点数:float(4字节) double(8字节) 初始值:0.0

  2. 字符型 char 初始值:0 对应的字符

  3. 布尔型 boolean 初始值:false

整型常量默认为 int 型,声明 long 型常量须后加‘l’(小写L) 或‘L’

浮点型常量默认为 double 型,声明 float 型常量,须后加‘f’ 或 ‘F’

引用类型:null

  1. 类(class)

  2. 接口(interface)

  3. 数组([ ])

当变量作为作为类成员使用时,java才确保给定其初始值,防止程序运行时错误。但是这些初始值对你的程序来说是不正确的。所以必须明确指定初始值。然而以上所诉并不适用于“局部”变量(即:非某个类的字段)。因此在某个方法中定义int i;那么变量i可能得到的是任一值。不会被初始化为0。所以使用前先付一个适当的值。如果忘记了,java会在编译时返回一个错误。告诉你此变量没有初始化。在类中定义一个对象的引用时,如果没有给定初始化值,此引用会默认为null值。 也就是说在java中基本类型的默认值是0,引用类型会默认为null

方法

形参: 形式上的参数 接受实参的数据 实参: 实际上的参数 传递的是真实的数据

值传递: 传递的是值的副本 引用传递: 传递的是引用地址

重载 方法名必须相同 形参列表不同,形参个数和类型和参数位置

为什么不能使用返回值类型区别方法重载? 在编译时,无法区分你调用的是那个方法

类和对象

面向过程

将事件分为步骤 每个步骤就是一个函数 性能高,耦合度高,可维护性差

面向对象

将事件分为一个一个对象进行的操作,每个对象的操作是一个函数 性能低,耦合度低,可维护性好

封装

将类的内部细节隐藏,对外提供访问的接口

多态体现方式
  1. 重载(编译时多态,静态的)(因为在编译时通过调用不同方法实现的)
  2. 重写(运行时多态,动态的,也称为动态绑定)(因为只有在运行期间在能确定执行对象的类型,然后再去调用子类对应的方法)
  3. 对象的多态性(动态的) Person p1 = new Man()
  4. 父类的引用指向子类的实例
  5. 编译时调用父类方法,执行时调用子类方法
  6. 编译时看左边,运行时看右边 对象多态的3个必要条件:
    1. 继承
    2. 重写
    3. 向上转型:比如 Person p1 = new Man() 将子类的引用地址赋予给父类对象
接口

接口中的变量,省略static final 关键字 方法省略 abstract 都是抽象方法 实现接口的类(实现类)必须要全部实现接口中的所有方法 不能被实例化,是多态的具体应用,具体实现是交给实现类(接口的引用指向的是实现类的实例)

常用类

数组既可以存储基本数据类型也能存储引用数据类型

集合只能存储引用数据类型

Collection接口、–>List接口、Set接口、(ArrayList… LinkedList… HashSet) Map接口等–>HashMap接口等,

JDBC (Java Database Connectivity)

JDBC的概述

JDBC(Java Database Connectivity),它是连接数据库与Java应用程序的桥梁。通过API方便地实现对各种主流数据库的操作

JDBC的常用类和接口

DriverManager 类

JDBC 的管理层,主要用于管理数据库中所有的驱动程序。

DriverManager类中的方法都是静态方法。

常用方法:

public static Connection getConnection(String url,String user,String password)
// 用于获取与指定数据库的连接,依次为连接数据库的URL、数据库的用户名和密码。
// 同时该方法会抛出SQLException异常
// 该方法使用的频率最高,同时它也是JDBC进行建立数据库连接的重要方法
public static int getLoginTimeout()
// 用于获取数据库驱动程序登录到指定数据库时可以等	待的最长时间,参数的单位为秒

public static void setLoginTimeout(int seconds)
// 用于对数据库驱动程序登录到指定数据库时最长等待	时间进行设置,参数的单位为秒

public static void println(String message)
// 该方法用于将一条消息打印到当前的JDBC日志流中
Connection接口

Connection接口代表了与特定数据库的连接,其实例就像是在Java应用程序与数据库之间开通的一条连接通道。

常用方法:

public Statement createStatement()
// 用于创建一个默认的 Statement 对象

public PreparedStatement prepareStatement(String sql)
// 用于创建预处理对象 PreparedStatement 

public boolean isReadOnly()
// 用于判断当前Connection对象的读取模式
    
public void setReadOnly()
// 用于对当前Connection对象的读取模式,默认情况下为非只读模式
    
public void close()
// 用于对当前Connection对象所占用的数据库和JDBC资源进行立即释放,而不是等待它们被自动释放

注意:

创建 PreparedStatement 对象时使用SQL语句做参数,会解析并编译SQL语句。也可以使用带占位符“?”的SQL语句做参数,在通过setXxx()方法给占位符赋值后执行SQL语句时无需再解析和编译SQL语句,直接执行的。当进行批处理(多次执行相同操作)时,效率高。

而创建 Statement 对象不使用SQL参数,不会解析并编译SQL语句,每次调用执行SQL语句时都要进行SQL语句的解析和编译操作,效率低。

Statement接口

Statement接口一般用于执行静态的SQL语句,其主要作用是将SQL语句传送给数据库,并将数据库执行SQL语句的结果返回给应用程序

常用方法:

execute(...)
// 执行给定的SQL语句,这可能会返回多个结果。 
// 一般是在我们不知道SQL语句执行后会产生什么结果或可能产生多种类型的结果时才会使用
    
executeQuery(...)
// 执行给定的SQL语句,该语句返回单个 ResultSet对象。SELECT 查询
    
executeUpdate(...)
// 执行给定的SQL语句,这可能是 INSERT,UPDATE或DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。
ResultSet接口

ResultSet接口封装了Statement接口中executeQuery()方法执行后返回的结果集,主要是用来暂时对数据库查询操作所获得的结果集进行存储

常用方法:

// 列号从1开始
boolean next()
// 将光标从当前位置向下移动一行
    
boolean previous()
// 游标从当前位置向上移动一行
    
void close()
// 关闭ResultSet 对象
    
int getInt(int colIndex)
// 以int形式获取结果集当前行指定列号 的值
    
int getInt(String colLabel)
// 以int形式获取结果集当前行指定列名 的值
    
float getFloat(int colIndex)
// 以float形式获取结果集当前行指定列号 的 值
    
float getFloat(String colLabel)
// 以float形式获取结果集当前行指定列名 的值
    
String getString(int colIndex)
// 以String 形式获取结果集当前行指定列号 的值
    
String getString(String colLabel)
// 以String形式获取结果集当前行指定列名 的值

注意:

在ResultSet对象中,列是从左至右进行编号的,并且从1开始

为了提高效率,建议使用getXXX()方法来获取数据库表中的对应字段的数据时,尽可能使用序列号作为参数

PreparedStatement接口

PreparedStatement接口是Statement接口的子接口,其主要是用来解决我们使用Statement对象多次执行同一条SQL语句时影响执行效率的问题

PreparedStatement对象是通过Connection对象的prepareStatement()方法创建

使用PreparedStatement接口进行SQL语句处理的一个特点是可以用于执行动态的SQL语句

在动态SQL语句时,我们使用“?”作为动态参数的占位符

Java语言中所提供的简单的数据类型,都可以在PreparedStatement接口中找到相对应的setXXX()方法

setXXX(int parameterIndex, XXX x)
// 第一个参数为int型,指示PreparedStatement对象中的第几个参数将要被初始化
// 第二个参数就是要被初始化参数的值
// 比如
setInt(int parameterIndex, int x) 
// 将指定的参数设置为给定的Java int值。
    
setArray(int parameterIndex, Array x) 
// 将指定的参数设置为给定的 java.sql.Array对象。
    
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?");

// 设置第一个问号的值                        
pstmt.setBigDecimal(1, 153833.00)
    
// 设置第二个问号的值
pstmt.setInt(2, 110592) 

使用JDBC连接并操作数据库

JDBC访问数据库的步骤

  1. 加载JDBC驱动
  2. 与数据库建立连接
  3. 创建Statement或PreparedStatement对象
  4. 发送SQL语句,并得到返回结果
  5. 释放资源
// 注意导入的包是在java.sql下

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCTest {
		public static void main(String[] args) {
 		// 初始化3个必须变量
 		ResultSet rs = null;
 		PreparedStatement psmt = null;
 		Connection conn = null;
 		
 		// 1. 加载JDBC驱动
 		try {
 			Class.forName("con.mysql.jdbc.Driver");
 			
 			// 2. 与数据库连接
 			String url = "jdbc:mysql://localhost:3306/(数据库名)?characterEncoding=utf-8";
 			String user = "root";
 			String password = "root";
 			
 			conn = DriverManager.getConnection(url, user, password);
 			
 			// 3. 创建Statement 或者 PreparedStatement对象
 			String sql = "select * from student where name= ?";			
 			// 4.发送执行SQL语句,并得到返回结果
 			psmt = conn.prepareStatement(sql);
 			// 给占位符赋值
 			// 赋予第一个问号
 			psmt.setString(1, "xxx");
 			// 执行 sql 返回结果  这里是查询用executrQuery
 			rs = psmt.executeQuery(); 
 			// 处理结果集
 			while (rs.next()) {
 				int id = rs.getInt(1);
 				String name = rs.getString(2);
 				System.out.println(id + "---" + name);
 			}
 		} catch (Exception e) {
 			// TODO: handle exception
 			e.printStackTrace();
 		}finally {
 			// 5.释放资源 先打开的后关闭,后打开的先关闭
 			try {
 				// 关闭
 				rs.close(); 
 				psmt.close();
 				conn.close();
 			} catch (SQLException e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
 		}
 	}
 } 


实际上我一般是封装 连接数据库 与 释放资源 ,封装 查询执行,封装 结果处理

一些相关面试问题

  1. java 创建对象的方式? 使用new 的方式 反射机制(透过现象看本质) 序列化 clone() 克隆

  2. char类型能不能存贮一个中文? 可以

  3. ==与equals()的区别 ==:比较的是两个引用在内存中指向的是否同一对象(即同一内存空间),也就是内存空间中的存储位置是否一致。 equals():比较的是内存空间存放的数据是否相同

  4. 重写与重载的区别

方法重载:是指同一个类中的多个方法具有相同的名字,但这些方法具有不同的参数列表,即参数的数量或参数类型不能完全相同

方法重写:是存在子父类之间的,子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型

重载:实现的是编译时的多态性

重写:实现的是运行时的多态性

重写 @Override // 重写的方法 规则: 子类重写方法返回值类型,形参列表必须和父类被重写一致 子类重写的方法的访问修饰符权限不能低于父类 访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private) 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

重载 就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。

​ 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性

  1. 如果父类只有有参构造方法,那么子类必须要重写父类的构造方法吗? 必须调用,重写

  2. this super关键字分别代表什么? this代表当前对象 super代表父类对象 静态方法里不能使用这两个关键字

  3. 什么是拆装箱? 装箱:将基本数据类型转化为包装类 拆箱:将包装类转化为基本数据类型

  4. 接口和抽象类的区别? 相同:都不能被实例化,都可以包含抽象方法, 不相同:抽象类可以包含其他非抽象方法 接口只能包含抽象方法 接口(interface)可以说成是抽象类的一种特例, 接口中的所有方法都必须是抽象的。 接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。

  5. java抽象类和普通类的区别

    抽象类不能被实例化。

    抽象类可以有构造函数,抽象方法不能被声明为静态。

    抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体

    含有抽象方法的类必须申明为抽象类

    抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类

  6. 抽象类是否可以有构造函数?

    可以有。抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生。不仅如此,抽线类的构造函数还有一种巧妙应用:就是在其内部实现子类必须执行的代码



奖励一下