今天为前面学的面向对象做一些知识点的补充
1. static关键字:
说明:
-
主要用来修饰类的内部结构属性、方法、代码块、内部类
-
static修饰的变量为静态变量
-
static修饰的方法为静态方法
-
static修饰的变量和方法都是可以通过类名直接调用的,参考Arrays、Math、Collections等工具类
-
静态方法内不能调用非静态的变量和方法,不能和this,super联用
-
非静态方法可以调用静态变量和方法
-
static修饰的代码块相当于项目的配置文件,存在于方法区中,只执行一次,参考jdbc
举例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.eclipse.jdt.internal.compiler.ast.NumberLiteral;
/*
* JDBC 工具类
*/
public class JDBCUtils {
private static final String driverClass;
private static final String url;
private static final String username;
private static final String password;
//注意这一段,static修饰的代码块,项目运行过程中只加载一次
static {
//这里在mysql8.0之后写法略微不同,为了举例就不改动了
driverClass = "com.mysql.jdbc.Driver";
url = "jdbc:mysql://127.0.0.1:3306/test";
username = "root";
password = "123456";
}
/*
* 注册驱动
*/
public static void loadDriver() throws ClassNotFoundException {
Class.forName(driverClass);
}
/*
* 获得连接
*/
public static Connection getConnection() throws Exception {
loadDriver();
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
/*
* 资源释放
*/
public static void release(Statement stmt, Connection conn) {
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn = null;
}
}
/*
* 释放资源
*/
public static void release(ResultSet rs, Statement stmt, Connection conn) {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rs = null;
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
conn = null;
}
}
- 应用场景:单例模式
单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点
-
单例模式保证了一个类只有一个实例
-
为该实例提供一个全局访问节点
代码举例:
//单例类
public class Singleton {
private static Singleton singleton = null;
//创建一个私有化的构造器
private Singleton() {
}
public static Singleton print() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
//测试类
public class Test {
public static void main(String[] args) {
//通过调用类中的静态方法获取对象
Singleton singleton = Singleton.print();
System.out.println(singleton);
}
}
运行结果:
其实多次运行以后打印出对象的地址值都不会变,这说明生成的对象没有发生变化,在使用环境中,客户甚至都不知道他们调用的是同一个对象
2. main()方法:
main()方法就是程序运行的入口,是现阶段最经常使用的方法
格式:
public static void main(String[] args){//方法体}
说明:
-
main()方法作为程序的入口
-
main()方法也是一个普通的静态方法
-
main()方法可以作为我们与控制台交互的方式,如键盘输入
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
或
Scanner sc = new Scanner(System.in);
- main方法的形参列表是一个字符串数组,输入进去的数值都会转变成字符串的类型
代码示例:
public class Test{
public static void main(String[] args){
System.out.println(args[2]); //打印输入的第三个元素
}
}
运行结果:
可以看到,输入的第三个元素true被转换成字符串格式打印出来了
3. Object类:
Object是所有类的父类,也叫"超类",所有的类都可以重写Object中的原有方法
Object类中只声明了一个空参的构造器
Object的方法有:
-
equals()
-
toString()
-
getClass()
-
hashCode()
-
clone()
-
finalize()
-
wait()
-
notify()
-
notifyAll()
这里就说几个常用的吧
- equals()
-
==是比较两个类型的值是否相同,一般用于基本数据类型之间的比较
-
equals比较两个对象的地址值是否相同,一般用于引用数据类型的比较
-
当要比较两个对象的"实体内容"是否相同时,可以重写类的equals方法
代码示例:
//学生类
public class Student {
private int id;//学号
private String name; //姓名
public Student() {
}
public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
//重写equals方法,比较学号和姓名是否相等
public boolean equals(Object obj) {
// TODO Auto-generated method stub
if (obj instanceof Student) {
Student s = (Student)obj;
if (this.getId() == s.getId() && this.getName().equals(s.getName())) {
return true;
}
}
return false;
}
}
//测试类
public class Test {
public static void main(String[] args) {
//初始化两个参数相同的对象
Student s1 = new Student(001,"学生1");
Student s2 = new Student(001,"学生1");
System.out.println(s1.equals(s2));
}
}
运行结果:
当没有重写Student类中的equals方法是,输出为false,感兴趣的可以去试试
- toString()
当我们打印一个对象时,其实是打印一个对象的地址值,也就是十六进制的哈希值,可读性不高,我们看不到这个对象的内部属性
这时我们可以重写这个类的toString方法,这个方法就相当于是这个类的自我描述
举例:
还是上面那个Student类,这里我们重写了toString方法
@Override
public String toString() {
// TODO Auto-generated method stub
return "学号: " + getId() + " ,姓名: " + getName();
}
测试类:
public class Test {
public static void main(String[] args) {
//初始化两个参数相同的对象
Student s1 = new Student(1,"小李");
System.out.println(s1);
}
}
输出结果:
可以看到,对象的属性值被输出了
这里要补充一点:当我们重写了类的toString()方法后,我们打印这个对象时们会自动调用这个对象的toString()方法
如果我们不重写toString()方法:
运行结果:
3. finalize()
finalize()方法用于对象的垃圾回收释放内存
JVM的垃圾回收有三种情况:
-
对象重写finalize方法可调用,调用该方法可直接将对象在内存中释放
-
System.gc() 通知JVM回收垃圾
-
直接给对象赋值为null,让JVM当作垃圾回收,回收时间未知
其他的方法并不常用,就只是理解了一下,不记录在这里了
4. 包装类:
包装类的出现是为了使基本数据类型的变量具有类的特征。
基本数据类型分别对应的包装类如下图所示:
基本数据类型,包装数据类型,String类型互相转换的方法如下图:
总的来说:
-
XXX.valueOf() 用于将基本类型转换为包装类型或String类型
-
XXX.parseInt()用于将String类型转换为包装类型
-
xxxValue() 用于将包装类型转换为基本数据类型
参考文章:
JDBC连接数据库模板