Java SE 基础

目录

一、什么是方法?

1.方法的格式

最简单的方法的定义和调用

带参数的方法的定义和调用

带返回值的方法的定义和调用

2.方法的重载

3.关于方法的两个练习

4.方法的内存

方法调用的基本内存原理

方法传递基本数据类型的内存原理

方法传递引用数据类型的内存原理

5.ststic 关键字

二、面向对象基础

1.类与对象

如何定义类

如何得到类的对象

如何使用对象

定义类的补充注意事项

2.构造方法

构造方法的格式

构造方法的注意事项

3.标准的JavaBean类

4.对象内存图

一个对象的内存图

两个对象的内存图

5.封装

private关键字

get和set方法

6.继承(extends)

继承的构造顺序

7.重写

8.super关键字

9.就近原则和this关键字

就近原则

this关键字的作用

this关键字的本质

10.final 关键字(最终)

11.访问权限

12.克隆

13.抽象类(abstract)

14.接口

三、字符串

字符串常用的一些方法

字符串的比较

StringBuffer 和 StringBuilder 区别

正则表达式

练习1--模拟用户登录

练习2--遍历字符串和统计字符次数

四、常用类

1.常用的数学类

2.包装类

一、什么是方法?

方法是程序中最小的执行单元

优点:1.提高代码的复用性 2.提高代码的可维护性

1.方法的格式

最简单的方法的定义和调用

定义格式:

public static void 方法名(){

方法体(就是打包起来的代码);

}

调用格式:

方法名();

带参数的方法的定义和调用

定义格式:

public static void 方法名(参数1,参数2,…){ //括号内参数称为行参

方法体(就是打包起来的代码);

}

调用格式:

方法名(参数1,参数2,…); //括号内参数称为实参

注意:形参和实参需要一一对应

带返回值的方法的定义和调用

使用场景:在调用处需要根据方法的结果,去编写另一段代码

定义格式:

public static 返回值类型 方法名(参数1,参数2,…){

方法体(就是打包起来的代码);

return 返回值;

}

调用格式:

直接调用:方法名(参数1,参数2,…); //一般用在无返回值的调用

赋值调用:数据类型 变量名 = 方法名(参数1,参数2,…);

输出调用:system.out.println(方法名(参数1,参数2,…));

2.方法的重载

定义:在同一个类中,方法名相同,参数不同(个数不同、类型不同、顺序不同)的方法,就是重载。与返回值无关。

//方法的重载
 public class MethodDome1 {
     /*需求:使用方法重载的思想,设计比较两个数是否相同的方法
          要求:兼容全整数类型(byte,short,int,long)*/
     public static void main(String[] args) {
         //调用
         compare(10,20);
         
         //compare((byte)20,(byte)30);
     }
 ​
     public static void compare(byte b1,byte b2){
         System.out.println("===byte===");
         System.out.println(b1==b2);
     }
     public static void compare(short s1,short s2){
         System.out.println("===short===");
         System.out.println(s1==s2);
     }
     public static void compare(int i1,int i2){
         System.out.println("===int===");
         System.out.println(i1==i2);
     }
     public static void compare(long l1,long l2){
         System.out.println("===long===");
         System.out.println(l1==l2);
     }
 }

3.关于方法的两个练习

 public class Exercise1 {
     public static void main(String[] args) {
         int[] arr1={11,22,33,44,55};
         //printArr(arr1);
 ​
 ​
         int[] arr2={1,45,7,10,3,6,8};
         //调用方法求最大值
         int max=getMax(arr2);
         System.out.println(max);
     }
 ​
     public static void printArr(int[] arr1){
         //需求:设计一个方法用于数组遍历,要求遍历的数组在一行上,例如:[11,22,33,44,55]
         System.out.print("[");
         for (int i = 0; i < arr1.length; i++) {
             if(i== arr1.length-1){
                 System.out.print(arr1[i]);
             }else {
                 System.out.print(arr1[i]+",");
             }
         }
         System.out.println("]");
     }
 ​
     public static int getMax(int[] arr2){
         //设计一个方法求数组的最大值,并将最大值返回
         int max=arr2[0];
         for (int i = 0; i < arr2.length; i++) {
             if (arr2[i]>max){
                 max=arr2[i];
             }
         }
         return max;
     }
 }

补充:return和break关键字的区别

return:和循环无关,和方法有关,表示1结束方法 2返回结果

如果方法执行到return,那么整个方法全部结束,里面的循环也随之结束

break:和方法无关,主要作用是结束循环或switch的

4.方法的内存

方法调用的基本内存原理

传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值

传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值

方法传递基本数据类型的内存原理

基本数据类型:数据值是存储在自己的空间中

方法传递引用数据类型的内存原理

引用数据类型:使用了其他空间中(堆)的数据,变量中存储的是地址值

5.ststic 关键字

二、面向对象基础

1.类与对象

类(设计图):是对象共同特征的描述 对象:是真实存在的具体东西

在java中,必须先设计类,才能获得对象

如何定义类

public class 类名{

1.成员变量(代表属性,一般是名词)

2.成员方法(代表行为,一般是动词)

3.构造器

4.代码块

5.内部类

}

如何得到类的对象

类名 对象名 = new 类名();

如何使用对象

访问属性:对象名.成员变量;

访问行为:对象名.方法名(...);

定义类的补充注意事项
  • 用来描述一类事物的类,专业叫做:Javabean类

在Javabean类中,是不写main方法的

  • 编写main方法的类,叫做测试类

我们可以在测试类中创建Javabean类的对象并进行赋值调用

  • 成员变量的完整定义格式是:

修饰符 数据类型 变量名称 = 初始化值;(一般无需指定初始化值,存在默认值)

2.构造方法

构造方法也叫构造器或构造函数。

作用:在创建对象的时候给成员变量进行初始化(赋值)的

构造方法的格式

public class Student{

修饰符 类名(参数) {

方法体;

}

}

特点:

  • 方法名与类名相同,大小写也要一致

  • 没有返回值类型,连void都没有

  • 没有具体的返回值(不能有return带回结果数据)

构造方法的注意事项

构造方法的定义:

  • 如果没有定义构造方法,系统将给出一个默认的无参数构造方法

  • 如果定义了构造方法,系统将不在提供默认的构造方法

构造方法的重载:

  • 带参构造方法和无参构造方法,两者方法名相同,但是参数不同,这叫做构造方法的重载

推荐使用方式:

  • 无论是否使用,都要手动书写无参数构造方法和带全部参数的构造方法

3.标准的JavaBean类

  • 类名需要见名知意

  • 成员变量使用private修饰

  • 提供至少两种构造方法

    • 无参构造方法

    • 带全部参数的构造方法

  • 成员方法

    • 提供每一个成员变量对应的setXxx()和getXxx()

    • 如果还有其他行为,也需要写上

4.对象内存图

一个对象的内存图

Student s = new Student ( );

  • 加载class文件

  • 声明局部变量

  • 在堆内存中开辟一个新空间

  • 默认初始化

  • 显示初始化

  • 构造方法初始化

  • 将堆内存中的地址值赋值给左边的局部变量

两个对象的内存图

注意:第二次在创建一个新对象的时候,不需要在方法区中加载一次字节码文件

5.封装

对象代表什么,就得封装对应的数据,并提供数据对应的行为

需要什么对象的时候,可查API帮助文档

private关键字
  • 是一个权限修饰符

  • 可以修饰成员(成员变量和成员方法)

  • 被private修饰的成员只能在本类中才能访问

get和set方法

快捷键:alt+insert

  • set方法:给成员变量赋值

  • get方法:对外提供成员变量的值

6.继承(extends)

作用:提高代码的复用性,简化代码

继承的构造顺序

在实例化子类时,先执行父类构造方法,再执行子类构造方法;调用时,默认先调用父类无参构造方法

注意:父类构造方法定义问题,一般需要留上一个无参构造方法。

如果父类中只有有参构造,没有无参构造时,子类在构造方法中先去调用父类的构造方法

补充:父类和子类的执行顺序:

父类static --- 子类static --- 父类属性和父类代码段 --- 父类构造方法 --- 子类属性和子类代码段 --- 子类构造方法

7.重写

多态:

  • 静态多态 ---- 重载 ---- 一个类中同名不同参

  • 动态多态 ---- 重写 ---- 父子类中同名同参

  • 多态的三个必备条件:1.继承 2.重写 3.父类指向子类对象的引用

软件设计原则:

  • OPC:开闭原则 ---- 对修改关闭对扩展开放

软件开发生命周期:

  • 可行性分析 --- 需求分析 --- 概要设计 --- 详细设计 --- 开发 --- 测试 --- 维护

  • 重写定义:子类中方法和父类中方法出现同名同参,称之为重写

  • @Override注解:用来检查是否符合重写规则

  • 两大一小原则:

    • 一大:子类重写方法访问权限大于或等于父类方法

    • 一小:子类重写方法返回值类型小于或等于父类方法(可以自动向上转型),不包括基本类型

    • 一小:子类方法抛出异常类型小于或等于父类方法抛出异常类型

  • instance of :运算符,判断实例是否属于指定类型;在判断时,把大类放在后面

8.super关键字

用法:

  • 调用父类构造方法:super.([参数列表]); ------------只能用在构造方法第一句

  • 调用父类普通成员(属性、方法、内部类):super.propName;super.methodName(); ------------可以用在构造方法也可用在普通方法,位置顺序没有限制

9.就近原则和this关键字

就近原则
  • System.out.println(age) 先到局部变量位置找值,如果没有,再到成员变量位置找值

  • System.out.println(this.age) 直接到成员变量位置找值

this关键字的作用

可以区别成员变量和局部变量

this关键字的本质

所在方法调用者的地址值

10.final 关键字(最终)

  • 修饰类:类不能被继承

  • 修饰方法:方法不能被重写

  • 修饰变量:变量变成常量,不能多次被修改赋值(常量命名全部大写,多个单词组合时,用下划线分开)。修饰的属性,在声明时,必须要初始化

扩展:

  • finalize() 是属于 Object 类中的方法

  • 作用:在垃圾回收器回收对象时,回去调用执行的方法。

11.访问权限

访问修饰符内部类同包下的类不同包下的类其他包的类
private可以访问不可以不可以不可以
默认的(同包)可以可以不可以不可以
protected可以可以可以不可以
public可以可以可以可以

12.克隆

克隆方法:

  • 重写 Object clone() 方法 ------ 可以把访问修饰权限改成 public

    •  @Override
       public Object clone() throws CloneNotSupportedException {
           return super.clone();
  • 实现可克隆的接口 ------- implements Cloneable

浅克隆和深克隆:

  • 浅克隆:只克隆基本类型或 String 属性,对于依赖的引用类型对象,只克隆了地址。

  • 深克隆:依赖的引用类型对象,也会进行克隆

13.抽象类(abstract)

  • abstract关键字修饰的类,称之为抽象类;

  • abstract修饰的方法,称之为抽象方法,抽象方法不能有方法体;

  • 拥有抽象方法的类,必须定义为抽象类,但抽象类中不一定有抽象方法;

  • 抽象类不能被实例化;

  • 子类继承抽象类时,要么实现抽象类中所有的抽象方法,要么把子类声明为抽象类;

  • 抽象类和普通类的区别:

    • 抽象类中可以有抽象方法,普通类不可以

    • 抽象类不能被实例化

14.接口

接口特点(多实现、多个功能):

  • 定义:interface

  • 属性:默认是且只能是 public static final 的常量

  • 方法:默认是且只能是 public abstract,可以省略

  • 构造:接口没有且不能定义构造方法

  • 内部类:默认是 public static 的内部类

  • 代码段:接口中不能使用代码段

解耦

 /*
 * 接口:规范、功能、标准
 * */
 public class TestInterface {
     public static void main(String[] args) {
         HuaWeiPhone phone=new HuaWeiPhone();
         IPlayer player=phone;   //手机是一个播放器
         phone.net();
         phone.play();
         phone.sendSMS();
         phone.takePhoto();
         phone.call();
     }
 }
 /*生产一个华为手机*/
 class HuaWeiPhone extends Phone implements ICamera,IPlayer,INet{
 ​
     @Override
     public void sendSMS() {
         System.out.println("=====发短信=====");
     }
 ​
     @Override
     public void takePhoto() {
         System.out.println("=====拍照片=====");
     }
 ​
     @Override
     public void play() {
         System.out.println("=====放音乐======");
     }
 ​
     @Override
     public void net() {
         System.out.println("======上网======");
     }
 }
 ​
 abstract class Phone{
     public abstract void sendSMS();
     public void call(){
         System.out.println("=====打电话=====");
     }
 }
 /*相机接口*/
 interface ICamera{
     void takePhoto();
 }
 /*播放器接口*/
 interface IPlayer{
     void play();
 }
 /*网络接口*/
 interface  INet{
     void net();
 }

三、字符串

创建String对象的两种方式

  • 直接赋值

  • 使用new关键字来获取字符串对象

字符串常用的一些方法
 public class TestString {
     public static void main(String[] args) {
         String srt = "yay.123.zbx     ";
         System.out.println("length():"+srt.length());  //长度
         System.out.println(srt.contains("zb"));   //是否包含
         System.out.println(srt.concat("xyz"));    //拼接
         System.out.println(srt.replaceAll("3","5"));   //替换
         System.out.println(srt.indexOf("."));    //查找第一个字符 . 所在的位置
         System.out.println(srt.lastIndexOf("."));   //从后面查找最后一个字符 . 所在的位置
         System.out.println(srt.charAt(2));   //给定下标找字符
         System.out.println(srt.substring(4,7));   //截取子串,注意,不包含后面位置的字符
         System.out.println(srt.substring(srt.indexOf(".")+1,srt.lastIndexOf(".")));
         System.out.println(srt.toLowerCase());   //全部转换为小写字母
         System.out.println(srt.toUpperCase());   //全部转换为大写字母
         System.out.println(srt.endsWith(".java"));   //是否以指定字符串结尾
         System.out.println(srt.startsWith("ya"));   //是否以指定字符串开头
         System.out.println("==="+srt.trim()+"===");    //去空格
     }
 }
字符串的比较
 public class StringCompare {
     public static void main(String[] args) {
         //1.创建两个字符串对象
         String s1=new String("abc");  //记录的是堆中的地址
         String s2="abc";   //直接赋值,记录的是串池中的地址
 ​
         //2.==号比较
         //基本数据类型:比的是数据值
         //引用数据类型:比的是地址值
         System.out.println(s1==s2);
         System.out.println("======");
 ​
         //3.比较字符串中对象的内容是否相等,完全一样  boolean equals
         boolean result1 = s1.equals(s2);
         System.out.println(result1);
         System.out.println("======");
 ​
         //4.比较字符串中对象的内容是否相等,忽略大小写  boolean equalsIgnoreCase
         boolean result2 = s1.equalsIgnoreCase(s2);
         System.out.println(result2);
     }
 }
StringBuffer 和 StringBuilder 区别
  • StringBuffer 方法都是有 synchronized 关键字修饰的

  • StringBuffer 线程同步的,安全的,效率低,推荐多线程场景使用

  • StringBuilder 非线程同步的,不安全的,相对效率高,推荐多线程场景下使用

正则表达式

作用:

  • 校验字符串是否满足一定的规则

  • 在一段文本中查找想要的内容

练习1--模拟用户登录
 /*已知正确的用户名和密码,请用程序模拟实现用户登录
  * 一共三次机会,登录之后,给出相应的提示*/
 public class Exercise1 {
     public static void main(String[] args) {
         //定义两个变量记录正确的用户名和密码
         String rightUsername = "zhangsan";
         String rightPassword = "123456";
 ​
         //键盘录入用户名和密码
         Scanner scanner = new Scanner(System.in);
         for (int i = 0; i < 3; i++) {
             System.out.println("请输入用户名:");
             String username = scanner.next();
             System.out.println("请输入密码:");
             String password = scanner.next();
 ​
             //比较
             if (username.equals(rightUsername) && password.equals(rightPassword)) {
                 System.out.println("用户登录成功!");
                 break;
             } else {
                 if (i == 2) {
                     //最后一次机会也登录错误,此时要提示账户被锁定
                     System.out.println("三次机会登录失败,账号" + username + "被锁定!");
                 } else {
                     System.out.println("用户登录失败,用户名或密码错误,您还有" + (2 - i) + "次机会!");
                 }
             }
         }
     }
 }
练习2--遍历字符串和统计字符次数

public char charAt(int index) 根据索引返回字符

public int length( ) 返回此字符串的长度

数组的长度:数组名.length

字符串的长度:字符串对象.length( )

public class Exercise2 {
     public static void main(String[] args) {
 //        Test1();
         Test2();
     }
 ​
     public static void Test1() {
         /*字符串遍历
          * 需求:键盘录入一个字符串,使用程序实现在控制台遍历该字符串
          */
         //键盘录入一个字符串
         Scanner scanner = new Scanner(System.in);
         System.out.println("请输入一个字符串:");
         String str = scanner.next();
 ​
         //进行遍历
         for (int i = 0; i < str.length(); i++) {
             //i依次表示字符串中的每个索引
             char c = str.charAt(i);
             System.out.print(c + " ");
         }
     }
 ​
     public static void Test2(){
         /*统计字符次数
         * 键盘录入一个字符串,统计该字符串中大写字母字符,
         * 小写字母字符,数字字符出现的次数(不考虑其他字符)
         */
         //1.键盘录入一个字符串
         Scanner scanner = new Scanner(System.in);
         System.out.println("请输入一个字符串:");
         String str = scanner.next();
         //2.统计---计数器思想++
         //定义三个计数器
         int bigCount=0;
         int smallCount=0;
         int numberCount=0;
         //3.进行遍历
         for (int i = 0; i < str.length(); i++) {
             //i一次表示字符串中的每个索引
             char c = str.charAt(i);
             if (c>='A'&&c<='Z'){
                 bigCount++;
             }else if (c>='a'&&c<='z'){
                 smallCount++;
             }else if (c>='0'&&c<='9'){
                 numberCount++;
             }
         }
         //4.打印
         System.out.println("大写字母有"+bigCount+"个!");
         System.out.println("小写字母有"+smallCount+"个!");
         System.out.println("数字字符有"+numberCount+"个!");
     }
 }

四、常用类

1.常用的数学类

public class TestMath {
     public static void main(String[] args) {
         System.out.println(Math.PI);
         System.out.println(Math.max(66,77));    //求两位数的最大值
         System.out.println(Math.min(45,67));    //求两位数的最小值
         System.out.println(Math.abs(-9));       //求绝对值
         System.out.println(Math.random());      //随机数,范围 [0,1)
         System.out.println(Math.pow(2,3));      //次方,2的3 次方
         System.out.println(Math.ceil(1.2));     //向上取整, ceil:天花板
         System.out.println(Math.floor(2.9));    //向下取整, floor:地板
         System.out.println(Math.round(1.6));    //四舍五入
     }
 }

2.包装类

包装类:基本数据类型对应的引用数据类型

/*
  *两种方式获取Integer对象的区别
  * */
 public class TestInteger {
     public static void main(String[] args) {
         //底层原理:
         //因为在实际开发中,-128~127之间的数据用的比较多
         //如果每次使用数据都是new一个新的对象,太浪费内存
         //所以,提前把这个范围中的每个对象创建好内存
         //如果要用到了不会创建新的,而是返回已经创建好的对象
         Integer i1 = Integer.valueOf(127);
         Integer i2 = Integer.valueOf(127);
         System.out.println(i1 == i2);  //true
 ​
         Integer i3 = Integer.valueOf(128);
         Integer i4 = Integer.valueOf(128);
         System.out.println(i3 == i4);  //false
 ​
         //因为有new关键字,在java中,每一次new都是创建了一个新的对象
         //所以下面两个对象都是new出来的,地址不一样
         Integer i5 = new Integer("127");
         Integer i6 = new Integer("127");
         System.out.println(i5 == i6);  //false
 ​
         Integer i7 = new Integer("128");
         Integer i8 = new Integer("128");
         System.out.println(i7 == i8);  //false
     }
 }

自动装箱:把基本数据类型自动变成其对应的包装类。

自动拆箱:把包装类自动变成其对应的基本数据类型。

注意:在 JDK5 以后,int 和 Integer 可以看做是同一个东西,因为他们在内部可以自动转化。

如何获取包装类对象? 不需要 new,不需要调用方法,直接赋值即可。