找回密码
 立即注册
首页 资源区 代码 JavaSE
粉押淫 2025-10-30 11:46:52
计算机基础知识

一、快捷键


  • Ctrl+C:复制
  • Ctrl+V:粘贴
  • Ctrl+A:全选
  • Ctrl+X:剪切
  • Ctrl+Z:撤销
  • Ctrl+S:保存
  • Alt+F4:关闭窗口
  • Shift+Dlete:永久删除
  • Win+D:回到桌面
  • Win+E:打开我的电脑
  • Win+R:打开运行
  • Ctrl+Shift+Esc:打开任务管理器
  • Win+Tab:切换应用
  • Win+R  输入cmd:打开cmd
二、常用Dos命令


  • 盘符切换
  • 查看当前目录下所有文件  dir
  • 切换目录  cd change directory->cd /d directory
  • 返回上一级  cd..
  • 清理屏幕  cls(clear screen)
  • 退出终端  exit
  • 查看版本  java -version
  • ping 命令
    ping www.baidu.com
  • 文件操作
    md(创建目录)
    rd(移除目录)
    cd>(创建文件)
    del(删除文件)
三、Markdown语法详解

视频教程
Java学习路线(java黑马学习路线)

一、Java基础(其他参考笔记)

(一)jdk安装与环境配置

jdk安装和配置环境教程视频
(二)IntelliJ IDEA

Ⅰ.开发工具(IntelliJ IDEA)安装

idea破解版安装教程视频
具体步骤
Ⅱ.idea开发java程序步骤


  • project(工程)->module(模块)->package(包)->class(类)
  • New project/module/package/class
  • 编译后的class文件在工程路径下的一个out文件夹里
Ⅲ.idea快捷键

1.png

Ⅳ.idea其他操作

视频教程

  • @Override(Override注解),它可以指定java编辑器,检查我们方法重写的格式是否正确
  • //lombok技术可以实现为类自动添加getter setter方法、无参构造器、toString方法等。
    (1)@Data //@Date注解可以自动生成getter setter方法、无参构造器、toString方法等
    (2)@NoArgsConstructor //自动生成无参构造器
    (3)@AllArgsConstructor //自动生成有参构造器
  • @FunctionalInterface //声明函数式接口的注解。标记函数式接口,编译器会检查,如果接口中有多个抽象方法,编译器会报错。
(三)Java基础语法

Ⅰ.注释


  • 单行注释://
  • 多行注释:/**/
  • 文档注释:/** */
Ⅱ.数据类型


  • 基本数据类型:4大类8种
    2.png

  • 引用数据类型:String
  • 随便写的整数字面量默认是int类型,加上L/l就是long类型的数据了
  • 随便写的小数字面量默认是double类型,加上F/f就是float类型的数据了
Ⅲ.标识符


  • 标识符就是名字
  • 标识符规则:由数字,字母,下划线,美元符等组成,且不能数字开头,不能用关键字,不能用特殊符号(&,%···)
Ⅳ.方法的一些注意事项


  • 方法可以重载


  • 一个类中,出现多个方法的名称相同,但它们的形参列表是不同的,那么这些方法就称为方法重载。(通过方法名称标记同一功能,通过参数进行差异化。)

  • 无返回值的方法中可以直接通过单独的return;立即结束当前方法的执行。
Ⅴ.自动-强制类型转换


  • 为什么要进行类型转换


  • 存在不同类型的变量赋值给其他类型的变量

  • 什么是自动类型转换


  • 类型范围小弟变量,可以直接赋值类型范围大的变量

  • 什么是强制类型转换


  • 默认情况下,大范围类型的变量直接赋值给小范围类型的变量会报错
  • 可以强行将类型范围大的变量、数据赋值给类型范围小的变量
    数据类型 变量=(数据类型)变量、数据

  • 强制类型转换有哪些需要注意的


  • 大转小可能出些数据丢失
  • 小数强制转换成整数是直接截断小数保留整数
Ⅵ.表达式的自动类型提升


  • 小范围的类型会自动转换成大范围的类型运算
  • 最终类型由表达式中的最高类型决定
  • byte short char式直接转换成int类型参与运算的
Ⅶ.输入-输出


  • 输入:System.out.println("");
  • 输出
    (1) 导包(告诉程序去JDK的哪个包中找扫描器技术):import java.util.Scanner;
    (2) 得到键盘扫描器对象(东西):Scanner sc=new Scanner(System.in);
    (3) 等待接收用户输入数据:String name=sc.next();/int age=sc.nexitInt();
Ⅷ.逻辑运算符


  • &:有一个为false、结果是false
  • &&:有一个为false、结果是false,但前一个为false,后一个条件就不执行了
  • |:有一个为true、结果是true
  • ||:有一个为true、结果是true,但前一个为true,后一个条件就不执行了
  • ^:相同是false、不同是true
Ⅸ.switch分支-穿透性


  • switch分支结构
点击查看代码
  1. switch(表达式){
  2.   case 值1:
  3.     执行代码...;
  4.     break;
  5.   case 值2:
  6.     执行代码...;
  7.     break;
  8.   ...
  9.   case 值n-1:
  10.     执行代码...;
  11.     braek;
  12.   default:
  13.     执行代码n;
  14. }
复制代码

  • 注意事项


  • 表达式类型只能是byte、short、int、char,JDK5开始1支持枚举,JDK7开始支持String、不支持double、float、long。
  • case给出的值不允许重复,且只能是字面量,不能是变量。
  • 正常使用switch的时候,不要忘记写break,否则会出现穿透现象。

  • 存在多个case分支的代码是一样时,可以把代码写到一个case块,其他case块通过穿透性能,穿透到该case块即可,这样可以简化代码。
Ⅹ.三种循环的使用(for、while、do-while)

for循环中,控制循环的变量只在循环中使用。while循环中,控制循环的变量在循环后还可以继续使用。
ⅩⅠ.跳转关键字


  • break:跳出并结束当前所在循环的执行。
  • 在Java中,带标签的break语句(如break OUT;)用于从多层嵌套的循环或代码块中直接跳出到指定的外层标签位置。
点击查看代码
  1. 标签名:
  2. for (初始化; 条件; 迭代) {
  3.     // 外层循环
  4.     for (初始化; 条件; 迭代) {
  5.         // 内层循环
  6.         if (某种条件) {
  7.             break 标签名; // 直接跳出到标签指定的循环之后
  8.         }
  9.     }
  10. }
  11. // 跳转到这里
复制代码

  • continue:用于跳出当前循环的当次执行直接进入循环的下一次执行。
ⅩⅡ.生成随机数


  • Math.random()反回[0.0,1.0)的随机数字,Math.random()返回一个double类型的值。
  • import java.util.Random;
    Random r=new Random();//得到一个随机数对象
    int luckNumber=r.nextInt(100)+1;//[0,99]+1=>[1,100]
ⅩⅢ.开平方

Math.sqrt(number)
ⅩⅣ.数组


  • 静态初始化数组,定义已经确定了数据
    数据类型[] 数组名={元素1,元素2,元素3,…};
    如:int[] arr={12,24,36};
  • 完整格式
    数据类型[] 数组名=new 数据类型[]{元素1,元素2,元素3,…};
    如:int[] arr=new int[]{12,24,36};
  • "数据类型[] 数组名"也可写成"数据类型 数字名[]"的形式,定义数组的三种方法
    1.String[] names={"",""};
    2.String names[]={"",""};
    3.String[] names=new String[]{"",""};
  • names.length: 获取数组的长度(元素个数)
  • 动态初始化数组定义数组时先不存入具体的元素,只确定数组存储的数据类型和数组的长度
    数据类型[] 数组名=new 数据类型[长度];
    int[] arr=new int[3];
  • 动态初始化数组元素默认值规则:
    3.png

(四)面向对象编程

面向对象三大特征:封装、继承、多态。

  • 对象
    特殊的数据结构,一个实体,有属性和行为。也可以理解为一张表。
  • 类(对象类)
    特殊的数据结构,有属性和行为。类只在计算机中加载一次。
  • 内存分配
    java在内存的JVM虚拟机上运行,JVM虚拟机又分为堆内存、栈内存和方法区一同执行程序。
    变量存在栈里,变量指向对象,对象存在堆里,对象指向类,类存在方法区,将方法区中的方法调到栈中执行
    万物皆对象,一个数据由一个对应的对象处理,我们设计对象时就是在设计类(对象的模板)。
Ⅰ.类的基本语法


  • 构造器
    (1)构造器(分为无参构造器和有参构造器):类中定义的方法,用来初始化对象,在类中定义的方法,称为方法,在类中定义的变量,称为属性。 名字与类名一致,无返回值,无返回值类型,无访问修饰符。
    (2)特点:创建对象时,对象会自动调用构造器,如果没有定义构造器,JVM会自动生成一个无参构造器。
    (3)应用场景:创建对象时,调用构造器,立即初始化对象成员变量的值。
    (4)注意:类默认有一个无参构造器(没有显示而已),若你自己定义了有参构造器,那么类默认的无参数构造器就没有了,此时如果还想用无参数构造器,就必须自己手写一个无参构造器出来。
  • this关键字
    (1)this 关键字:是一个变量,可以用在方法中,用来拿到当前对象;哪个对象调用方法,this就指向哪个对象,也就是拿到哪个对象。
    (2)应用场景:用来解决对象的成员变量与方法内部变量的名称一样时,导致访问冲突问题的。
点击查看代码
  1. public void print(String name){//this关键字解决变量冲突问题
  2.     System.out.println(name+this.name);//this.name拿到的是对象变量(成员变量)name,而不是局部变量name
  3. }
复制代码

  • 封装
    (1)就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理这些数据的方法,设计到一个对象中去。
    (2)封装的设计要求:合理隐藏、合理暴露。
    (3)(合理隐藏)使用private(私有、隐藏)关键字进行修饰,防止用户在其他类中随意对本类内的变量修改数据,只允许在本类中直接被访问。
    (3)(合理暴露)使用get和set方法,用public(公开)进行修饰,让用户在类外直接调用,修改数据。
  • 实体类(JavaBean)
    (1)实体类:仅仅只是一个用来保存数据的java类,可以用它创建对象,保存某个事物的数据。
    (2)特点:成员变量必须私有,提供get和set方法;必须有无参构造器。
    (3)应用场景:实体类的对象只负责数据的封装,不涉及任何业务逻辑。而数据的业务处理交给其他类的对象来完成,以实现数据和业务处理相分离(解耦)。
  • static修饰成员变量
    (1)static关键字:叫静态,可以修饰成员变量、成员方法。
    (2)静态变量(类变量):有static修饰,属于类,在计算机里只有一份,被类的全部对象共享,所有对象都可以访问。
    类名.静态变量(推荐)
    对象名.静态变量(不推荐)
    (3)实例变量(对象的变量):没有static修饰,属于每个对象,每个对象都有自己的变量,对象可以访问。
    对象.实例变量
    (4)应用场景:如果某一个数据只需要一份,并且希望能够被共享(访问、修改),则该数据被定义成静态变量。 (如用户类,记录了创建了多少个用户对象)
    (5)访问自己类中的类变量,可以省略类名不写。
    注意:在某个类中访问其他类里的类变量,必须带类名。
  • static修饰方法
    (1)(有static修饰)静态方法:有static修饰的成员方法,属于类,最好用类名调用,少用对象名调用。
    (2)(无static修饰)实例方法:无static修饰的成员方法,属于对象,用对象名调用,不能用类名调用。
    规范:如果一个方法只是为了做一个功能且不需要直接访问对象的数据,这个方法直接定义为静态方法。
    如果这个方法是关于对象的行为,需要访问对象的数据,这个方法必须定义为实例方法。
    (3)比如在main方法中,我们直接调用其他方法,是用类名调用,只不过类名在同一类中可以忽略不写。(main方法是静态方法)
  • 工具类与静态方法
    (1)工具类:封装了多个静态方法,每个方法用来完成一个功能,给开发人员直接使用。
    (2)区别:实例方法需要创建对象来调用,此时对象占用内存,而静态方法不需要,可以减少内存消耗;静态方法可以用类名调用,调用方便,能节省内存。
点击查看代码
  1. public class StaticAbout {//工具类
  2.     //工具类没有创建对象的必要性,建议将工具类的构造器私有化。
  3.     private StaticAbout() {
  4.     }
  5.     public static String getCode(int n) {//静态方法与工具类
  6.         String code = "";
  7.         for (int i = 0; i < n; i++) {
  8.             int type = (int) (Math.random() * 3);//0-9 1-26 2-26
  9.             switch (type) {
  10.                 case 0:
  11.                     code += (int) (Math.random() * 10);
  12.                     break;
  13.                 case 1:
  14.                     code += (char) (Math.random() * 26 + 'a');//得到小写字母的区间
  15.                     break;
  16.                 case 2:
  17.                     code += (char) (Math.random() * 26 + 'A');
  18.             }
  19.         }
  20.         return code;
  21.     }
  22. }
复制代码

  • 静态方法与实例方法访问注意事项
    (1)静态方法中可直接访问静态成员,不可直接访问实例成员。
    (2)实例方法中即可直接访问静态成员,也可直接访问实例成员。
    (3)实例方法中可以出现this关键字,静态方法中不可出现this关键字。
点击查看代码
  1. public class Attention{
  2.     public static int count=100;//静态变量
  3.     public static void print(){//静态方法
  4.         System.out.println("Hello World!");
  5.     }
  6.     public String name;//实例变量,属于对象
  7.     public void prints(){//实例方法,属于对象
  8.     }
  9.     public static void main(String[] args) {
  10.     }
  11.     //(1)、静态方法中可直接访问静态成员,不可直接访问实例成员。
  12.     public static void printTest1(){
  13.         System.out.println(count);
  14.         print();
  15.         //System.out.println(name);//报错
  16.         //prints();//报错
  17.         //System.out.println(this);//报错,this代表的只能是对象
  18.         System.out.println(Attention.count);
  19.     }
  20.     //(2)、实例方法中即可直接访问静态成员,也可直接访问实例成员。
  21.     public void printTest2(){
  22.         System.out.println(count);
  23.         print();
  24.         System.out.println(name);
  25.         prints();
  26.         System.out.println(this);//实例方法中,this代表的是当前对象
  27.     }
  28. }
复制代码
Ⅱ.面向对象高级

一)继承


  • 继承
    (1)继承关键字:extends,可以让一个类与另一个类建立起父子关系
    public calss B extends A{}//其中A是父类,B是子类
    (2)只能继承父类的非私有成员(成员变量、成员方法)
    (3)继承后的创建:子类的对象是由子类、父类共同完成的。
    (4)继承的好处:代码重用,减少代码量,提高效率。
  • 权限修饰符
    用来限制类中的成员(成员变量、成员方法、构造器)能够被访问的范围。
修饰符本类里同一个包中的其他类子孙类(包括不同包的)任意类private√缺省√√protected√√√public√√√√点击查看代码
  1. public class Father {
  2.     private void privateMethod() {//二、2、权限修饰符之私有方法
  3.         System.out.println("private method");
  4.     }
  5.     void defaultMethod() {//二、2、权限修饰符之缺省方法
  6.         System.out.println("default method");
  7.     }
  8.     protected void protectedMethod() {//二、2、权限修饰符之受保护方法
  9.         System.out.println("protected method");
  10.     }
  11.     public void publicMethod() {//二、2、权限修饰符之公共方法
  12.         System.out.println("public method");
  13.     }
  14.     public static void main(String[] args) {//本类中可以调用的所有方法
  15.         Father father = new Father();
  16.         father.privateMethod();
  17.         father.defaultMethod();
  18.         father.protectedMethod();
  19.         father.publicMethod();//所有类都可以调用public方法
  20.     }
  21. }
  22. //以下为同一包的子类
  23. class SonA extends Father {
  24.     public void test() {
  25.         //privateMethod();//子类中不可以访问父类的私有方法
  26.         defaultMethod();//子类中可以访问父类的缺省方法
  27.         protectedMethod();//子类中可以访问父类的受保护方法
  28.         publicMethod();//子类中可以访问父类的公共方法
  29.     }
  30. }
  31. //以下为不同包的子类
  32. class SonC extends Father {
  33.     public void test() {
  34.         //privateMethod();//子类中不可以访问父类的私有方法
  35.         //defaultMethod();//不同包的子类中可以访问父类的缺省方法
  36.         protectedMethod();//不同包的子类中可以访问父类的受保护方法
  37.         publicMethod();//不同包的子类中可以访问父类的公共方法
  38.     }
  39. }
  40. //以下为不同包的非子类
  41. class main {
  42.     public static void main(String[] args) {
  43.         Father father = new Father();
  44.         //father.privateMethod();
  45.         //father.defaultMethod();
  46.         //father.protectedMethod();
  47.         father.publicMethod();//其他包中,只能访问public方法
  48.     }
  49. }
复制代码

  • 继承的特点
单继承一个类只能继承一个直接父类多层继承不支持多继承,但支持多层继承(多继承的话若两个父类出现相同方法,无法判断调用哪个)祖宗类Java中的所有类都是Object类的子类(一个类要么直接继承Object,要么默认继承Object,要么间接继承)就近原则优先访问自己类中,自己类中的没有才访问父类,父类也没有就报错(访问父类的成员要加super)点击查看代码
  1. public class TestFeature{//测试类
  2. //二、3、继承的特点
  3.     public static void main(String[] args) {
  4.         zilei zi=new zilei();
  5.         zi.test();
  6.     }
  7. }
  8. class fulei{
  9.     String name="FUlei";
  10.     public void run(){
  11.         System.out.println("fuleiRun");
  12.     }
  13. }
  14. class zilei extends fulei{
  15.     String name="ZiLei";
  16.     public void run(){
  17.         System.out.println("zileiRun");
  18.     }
  19.     public void test(){
  20.         String name="ZiLeiTEST";
  21.         System.out.println(name);//test的name
  22.         System.out.println(this.name);//zilei的name
  23.         System.out.println(super.name);//fulei的name
  24.         run();//zilei的run优先级更高
  25.         this.run();//zilei的run
  26.         super.run();//fulei的run
  27.     }
  28. }
复制代码

  • 方法重写(声明不变,重新实现)
    (1)重写小技巧:使用Override注解(@Override),它可以指定java编辑器,检查我们方法重写的格式是否正确,代码的可读性也会更好。
    (2)方法重写:子类写了一个方法名称,形参列表与父类某个方法一样的方法去覆盖父类的该方法。
    (3)子类重写父类方法时,访问权限必须大于或等于父类的该方法的权限(public>protected>缺省)
    (4)重写的方法返回值类型,必须与被重写方法的返回值类型一样,或者范围更小。
    (5)私有方法(不能被继承所以不能被重写)和静态方法(自己调用)不能被重写,否则报错。
点击查看代码
  1. public class TestOverride {
  2.     public static void main(String[] args) {//二、4、方法重写
  3.          animal a=new cat();
  4. //用父类申明对象,利用多态性和向上转型的概念,以实现更加灵活和可扩展的程序设计,降低代码的耦合性
  5.          a.eat();
  6.          cat b=new cat();
  7.          b.eat();
  8.     }
  9. }
  10. class animal{
  11.     public void eat(){System.out.println("animal eat");}
  12. }
  13. class cat extends animal{
  14.     @Override//方法重写的校验注解(标志),要求重写的方法与父类方法签名一致,否则编译报错,可读性好
  15.     public void eat(){System.out.println("cat eat!!!");}
  16. }
复制代码

  • 重写toString方法
点击查看代码
  1. public class TestOverride {
  2.     public static void main(String[] args) {
  3.          animal a=new animal();
  4.          System.out.println(a);
  5. //若没重写toString方法,则返回:com.rasion.extendANDpolymorphism.extend.cat@4e50df2e
  6.          System.out.println(a.toString());
  7.         //我们直接输出对象,会默认调用Object的toString方法,返回对象的地址信息
  8.         //故我们可以重写toString方法,返回我们想要的信息
  9.     }
  10. }
  11. class animal{
  12.     private String name;
  13.     @Override
  14.     public String toString() {//重写toString方法,返回我们想要的信息
  15.         return "animal{" +
  16.                 "name='" + name + '\'' +
  17.                 '}';
  18.     }
  19. }
复制代码

  • 子类构造器
    (1)子类构造器,必须先调用父类的构造器,再执行自己的构造器。(可以用super(···)指定调用父类的有参构造器)
    (2)默认情况下,子类构造器第一行代码都是super()(写不写都有),他会调用父类的无参构造器,若父类没有无参构造器,则报错。
    (3)如果父类没有无参构造器,则我们必须在子类构造器的第一行手写super(···),指定去调用父类的有参数构造器。
    (4)应用场景:有一些参数是处在父类中,子类没有,但子类需要用到,这时,子类构造器中,可以先调用父类的有参构造器,为对象中包含父类这部分的成员变量进行赋值,再调用子类的构造器。
  • 构造器用this(...)调用兄弟构造器(实现填写默认信息)
    (1)一般调用兄弟构造器(在构造器中调用本类的其他构造器),可以实现代码复用。
    (2)注意:super(..) this(...)必须写在构造器第一行,并且不能同时出现。(兄弟构造器只需要一个调用父类构造器即可)
点击查看代码
  1. public class User{
  2.     private String name;
  3.     private int age;
  4.     private String school;
  5.     //...此处省略get、set方法toString方法
  6.     public User(String name, int age) {
  7.         this(name, age, "黑马");//调用本类其他构造器,以实现填写默认信息
  8.     }
  9.     public User(String name, int age, String school) {
  10.         this.name = name;
  11.         this.age = age;
  12.         this.school=school;
  13.     }
  14. }
复制代码
二)多态


  • 多态
    (1)多态是在继承/实现的情况下的一种现象,表现为:对象多态、行为多态(对象的多样性,行为的多样性,但是没有成员变量的多态性)
    (2)多态前提:有继承/实现关系;存在父类引用子类对象;存在方法重写
    (3)注意:多态是对象、行为的多态,java中的属性(成员变量)不谈多态。
点击查看代码
  1. people p1=new student();//对象多态
  2. p1.run();//行为多态
  3. people p2=new teacher();//对象多态
  4. p2.run();//方法:编译看左边,运行看右边
  5.         
  6. System.out.println(p2.name);//成员变量:编译看左边,运行也看左边
复制代码

  • 多态的好处、问题
    (1)在多态形式下,右边的对象是解耦合的,更便于扩展和维护。
    (2)定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强、更便利。
    (3)问题:多态下不能使用子类的独有功能。
点击查看代码
  1. public class TestPolymorphism {
  2.     public static void main(String[] args) {
  3.         people p1=new student();//多态调用不了子类的独有功能
  4.         people p2=new teacher();
  5.         show(p1);
  6.         show(p2);
  7.         System.out.println(p1.name);//成员变量:编译看左边,运行也看左边
  8.     }
  9.     public static void show(people p) {
  10.         //父类类型作为参数,可以接收一切子类变量
  11.         System.out.println("=====+++=====");
  12.         p.run();//调用方法:编译看左边,运行看右边
  13.     }
  14. }
复制代码

  • 多态下的类型转换(instanceof判断)
    (1)自动类型转换:父类 变量名=new 子类();例如:People p=new Teacher();
    强制类型转换:子类 变量名=(子类) 父类变量;例如:Teacher t=(Teacher)p;
    (2)可以把对象转换成其真正的类型,从而解决了多态下不能调用子类独有方法的问题。
    (3)存在继承/实现时,就可以进行强制类型转换,编译阶段不会报错。
    但在运行时,如果发现对象的真实类型与强制转换后的类型不同,就会报类型异常(ClassCastException)的错误
    (4)在强转前可以用instanceof关键字判断对象的真实类型,再进行强转:对象 instanceof 类型
点击查看代码
  1. public class TestPolymorphism {
  2.     public static void main(String[] args) {
  3.         people p1=new student();
  4.         people p2=new teacher();
  5.         student s=(student)p1;//强制类型转换
  6.         //teacher t=(teacher)p1;//转换错误,因为p1是student类型
  7.         //编译阶段有类型强转不会报错,运行阶段会报错
  8.         show(p1);
  9.         show(p2);
  10.     }
  11.     public static void show(people p) {
  12.         if(p instanceof teacher) {//判断类型,一般会在方法中写,来判断p是否为teacher类型
  13.             teacher t=(teacher)p;
  14.             ...//调用teacher的独有功能
  15.         }else if(p instanceof student) {
  16.             student s=(student)p;
  17.             ...//调用student的独有功能
  18.         }
  19.     }
  20. }
复制代码
三)包


  • 包就是文件夹,用来管理各种不同功能的java类。
  • 包名的书写规则:公司域名反写+包的作用,需要全部英文小写,见名知意。
  • 全类名:包名+类名
  • 导包
    (1)使用同一个包中的类时,不需要导包。
    (2)使用java.lang包中的类时,不需要导包。
    (3)其他情况都需要导包。
    (4)如果同时使用两个包中的同名类,需要用全类名。
四)final(最终的)


  • final关键字用来修饰类、方法、变量。
    (1)修饰类:代表该类不能被继承,为最终类。(一般是用在工具类中)
    (2)修饰方法:代表该方法不能被重写,为最终方法。
    (3)修饰变量(局部变量、成员变量(静态、实例)):代表该变量有且仅能被赋值一次。(一般是修饰静态变量)
    (4)final修饰基本类型(int,double,boolean,char...)的变量,变量存储的数据不能被改变。
    (5)final修饰引用类型(String,Array...)的变量,变量存储的地址不能被改变,但地址所指向的对象的内容是可以被改变的。
    2、常量
    (1)使用了static final修饰成员变量为常量
    (2)作用:通常使用常量记录系统配置信息;常量都统一到常量包内(Constant),方便修改。
    (3)注意!常量名的命名规范:建议使用大写英文单词,多个单词使用下划线连接起来。
    (4)程序编译后,常量会被“宏替换”:出现常量的地方全部会被替换成其记住的字面量,减少内存消耗,这样可以保证使用常量和直接使用字面量的性能是一样的。
点击查看代码
  1. public class Constant {//常量包
  2.     public static final String NAME = "rasion";
  3. }
复制代码
五)单例类(设计模式)


  • 什么是设计模式:程序中一个问题n种解法中的最优解(设计模式主要学:解决什么问题、怎么写)(设计模式有20多种,对应20多种软件开发中会遇到的问题)
  • 单例设计模式
    (1)作用:确保某个类只有只能创建一个对象。
    (2)把类的构造器私有。(确保单例类对外不能创建太多对象,单例才有可能性)
    (3)定义一个类变量存储本类的一个唯一对象。
    (4)定义一个类方法,返回这个类的唯一对象。
  • 单例应用场景:任务管理器对象、获取运行时对象(有且仅需要一个对象)
  • 饿汉式单例类:在获取类的对象时,对象已经创建好了。
点击查看代码
  1. public class A {//饿汉式单例类:拿对象的时候对象早已生成,无论是用不用,都会创建。
  2.     private A(){}//1、私有化构造器
  3.     private static A a=new A();//2、实例化私有静态变量
  4.     //当类被加载时,静态变量a会被初始化,此时类的私有构造函数会被调用。这时候,单例类的唯一实例就被创建出来了。
  5.     public static A getObject(){
  6.         return a;
  7.     }//3、定义一个类方法返回对象
  8. }
复制代码

  • 懒汉式单例类:用对象时,才开始创建对象(延迟加载对象)。
    (1)把类的构造器私有。
    (3)定义一个静态(类)变量用于存储对象。
    (4)提供一个静态(类)方法,保证返回的是同一个对象。
点击查看代码
  1. public class B {//懒汉式单例类:拿对象的时候才创建,真正需要对象时才开始创建。
  2.     private B(){}//1、私有化构造器
  3.     private static B b;//2、定义一个类变量用于存储对象
  4.     public static B getInstance(){//提供一个类方法返回类的唯一对象
  5.         if(b==null){
  6.            //第一次拿对象时,会创建对象,给静态变量b记住。
  7.            b=new B();
  8.         }
  9.         return b;
  10.     }
  11. }
复制代码
六)枚举类(一种特殊类)


  • 枚举类的写法:
    修饰符 enum 枚举类名{
    名称1,名称2,名称3;
    其他成员...
    }
  • 特点:
    (1)枚举类中的第一行,只能写枚举类的对象名称,且要用逗号隔开。
    (2)这些名称,本质是常量,每个常量都记住了枚举类的一个对象。
    (3)枚举都是最终类,不可以被继承,枚举类都是继承java.lang.Enum类的。
点击查看代码
  1. public enum A {//枚举类
  2.     X,Y,Z;//枚举类第一行只能罗列一些名称,这些名称都为常量,并且每个常量会记住枚举类的一个对象
  3. }
  4. Compiled from "A.java"//对A.java的反编译
  5. public final class A extends java.lang.Enum{//枚举类继承了Enum
  6.     public static final A X=new A();//枚举类第一行只能罗列一些名称,这些名称都为常量,并且每个常量会记住枚举类的一个对象
  7.     public static final A Y=new A();//如果只有一个Y的话,可以被视为单例类。
  8.     public static final A Z=new A();
  9.     //枚举类的构造器都是私有的(写不写都只能是私有的),因此,枚举类对外不能创建对象。
  10.     public static A[] values();//返回枚举类的所有实例
  11.     public static A valueOf(java.lang.String var0);//返回指定名称的枚举实例
  12. }
复制代码

  • 枚举类的常用应用场景:适合做信息分类和标志
    (1)枚举类常用于定义常量,枚举类中的常量只能是枚举类的实例,不能被修改。
    (2)虽说用也可以用常量类做信息分类和标志,但是参数值不受约束(就是传入的参数不是限定内的那四个都能行的通,写别的不报错),但是枚举类的话写限定外的就会报错。
七)抽象类


  • 在java中有一个关键字叫:abstract(抽象),可以用它修饰类、成员方法
  • abstract修饰类,这个类就是抽象类
  • abstract修饰方法,这个方法就是抽象方法
    修饰符 abstract class 类名{
    修饰符 abstract 返回值类型 方法名称(形参列表);
    }
    抽象方法只有方法签名,不能写方法体。
  • 抽象类的注意事项、特点
    (1)抽象类不一定要有抽象方法,有抽象方法的类必须是抽象类
    (2)类有的成员:成员变量、方法、构造器,抽象类都可以有。
    (3)抽象类最主要的特点:抽象类不能创建对象,仅作为一种特殊的父类,让子类继承并实现
    (4)一个类继承抽象类,必须重写完抽象类的全部抽象方法,否则这个类也必须定义为抽象类。
点击查看代码
  1. public abstract class A {//抽象的本质是不能有对象,抽象类的基本作用就是被继承
  2.     private String name;//抽象类有成员变量
  3.     public A(){System.out.println("抽象类A的构造方法");}//抽象类有构造方法
  4.     public void show(){System.out.println("抽象类A的show方法");}//抽象类的方法可以有方法体
  5. //抽象方法,抽象类中可以有没有抽象方法,抽象方法没有方法体,只有方法声明,子类必须重写抽象方法
  6.     public abstract void show();//抽象类的抽象方法不能写方法体
  7. }
复制代码

  • 抽象类的应用场景和好处:父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们抽出这样的抽象类,就是为了更好的支持多态。(抽象类简化了需要重写的父类方法的代码,更加便于调用子类时多态的实现,更具解耦性。)
  • 模板方法设计模式:
    (1)提供了方法作为完成某类操作的模板,模板方法封装了每个实现步骤,允许子类实现特定步骤的实现。
    (2)解决方法中存在重复代码的问题。
    (3)定义一个抽象类,在里面定义2个方法,一个是模板方法:放相同的代码,一个是抽象方法:具体实现交给子类完成。
    (4)建议使用final关键字修饰模板方法。(模板方法不能被子类重写,一旦子类重写了模板方法,模板方法就失效了)
点击查看代码
  1. public abstract class fu {//父类抽象类
  2.     public final void show(){//模板方法不能被重写
  3.         System.out.println("模板方法");//子类共同的部分
  4.         show1();//子类不同的部分
  5.     }
  6.     public abstract void show1();//抽象方法,子类一定要重写,不然就报错,这样做是最佳实现
  7. }
  8. public class A extends fu {//子类
  9.     @Override
  10.     public void show1(){System.out.println("A show1方法");}
  11. }
  12. public class B extends fu {//子类
  13.     @Override
  14.     public void show1(){System.out.println("B show1方法");}
  15. }
复制代码
八)接口(相当于干爹)


  • Java提供了一个关键字interface定义出接口。
    public interface 接口名{
    //成员变量(常量)
    //成员方法(抽象方法)
    }
    (1)传统接口:内部只能写常量和抽象方法(jdk8以前)。
    (2)常量:接口中的常量默认是public static final的,所以可以省略。
    (3)抽象方法:接口中的抽象方法默认是public abstract的,所以可以省略。
    (4)没有构造方法。
  • 注意:接口不能创建对象。
  • 接口是用来被类实现(implements)的,实现接口的类称为实现类,一个类可以同时实现多个接口
    修饰符 class 实现类类名 implements 接口1,接口2,接口3,···{
    //实现类实现多个接口,必须重写完全部接口的全部抽象方法,否则实现类需要定义成抽象类。
    }
点击查看代码
  1. public interface A {//接口不能创建对象,只能被实现
  2. //JDK-8之前,接口只能定义常量和抽象方法,不能定义具体方法。
  3. //1、常量:接口中的常量默认是public static final的,所以可以省略。
  4.     String NAME="rasion";
  5.     //2、抽象方法:接口中的抽象方法默认是public abstract的,所以可以省略。
  6. //    public abstract void show();
  7.     void show();
  8. }
  9. public class C implements A,B {//实现接口的类,可以实现多个接口
  10.     @Override
  11.     public void show() {
  12.         System.out.println("C实现A\B接口的show方法");
  13.     }
  14. }
复制代码

  • 接口的好处:
    (1)弥补了类单继承的不足,可以实现多接口,使类的角色更多,功能更加强大(接口可以是一种属性)。
    (2)让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现(更利于程序的解耦合)。
点击查看代码
  1. public class test {
  2.     public static void main(){
  3. //        Driver d=new Teacher();//做接口解耦合,可以不改变自己本来的代码
  4.         Driver d=new Student();
  5.         Cook c=new Student();
  6.     }
  7. }
  8. public interface Driver {}
  9. public interface Cook {}
  10. class people{}//抽象类
  11. class Teacher extends people implements Driver,Cook{}//实现多个接口,用逗号隔开
  12. class Student extends people implements Driver,Cook{}
复制代码

  • JDK8开始,接口新增了三种形式的方法:
    (1)默认方法:使用default修饰,使用实现类的对象调用。
    (2)静态方法:static修饰,必须当前接口名来调用。
    (3)私有方法:private修饰,jdk9开始才有的,只能在接口内部被调用。
    (4)他们都会默认被public修饰。
    (5)新增的方法增强接口能力,更便于项目扩展与维护(若新增方法,可以直接写在接口中,不用修改实现类,更方便扩展)
点击查看代码
  1. //jdk-8之后的三种方法
  2.     //a、默认方法,一定要加default修饰符,默认会用public修饰,用接口的实现类对象调用
  3.     default void defaultMethod(){
  4.         System.out.println("defaultMethod");
  5.         privateMethod();
  6.     }
  7.     //b、静态方法,一定要加static修饰符,默认会用public修饰,只能用当前接口名来调用
  8.     static void staticMethod(){//静态方法
  9.         System.out.println("staticMethod");
  10.     }
  11.     //c、私有方法,一定要加private修饰符,默认会用private修饰,用接口中的其他实例方法调用
  12.     private void privateMethod(){//私有方法
  13.         System.out.println("privateMethod");
  14.     }
复制代码

  • 注意事项:
    (1)接口与接口可以多继承,一个接口可以同时继承多个接口,但接口不能继承类。
    类与类:单继承,一个类只能继承一个直接父类。
    类与接口:多实现,一个类可以同时实现多个接口

    (2)一个接口继承多个接口,若多个接口中出现方法签名冲突,此时不支持多继承,也不支持多实现(即两个接口都有同一个方法名,但是方法签名不同,即方法类型不同,则报错)。
    (3)一个类继承了父类,同时又实现接口,若父类与接口中有同名的方法,则会优先实现父类的方法。(若想调用接口的方法只能新建中专方法,接口名.super.方法名)
    (4)一个类实现多个接口,如果多个接口中存在同名的默认方法,要想不冲突,这个类重写该方法即可。
  • 抽象类与接口区别:
    相同点:
    (1)都是抽象形式,都可以有抽象方法,都不能创建对。
    (2)都是派生子类形式:抽象类是被子类继承使用,接口是被实现类实现。
    (3)一个类继承抽象类,或者实现接口,都必须重写他们的抽象方法,否则自己要成为抽象类或者报错!
    (4)都能支持多态,都能实现解耦合。
    不同点:
    (1)抽象类中可以定义类的全部普通成员,接口只能定义常量、抽象方法,(JDK8新增的三种方式)。
    (2)抽象类只能被类单继承,但是接口可以被类多实现。
    (3)一个类继承抽象类就不能再继承其他类,一个类实现了接口(还可以继承其他类或者实现其他接口)。
    (4)抽象类体现模板思想,更利于做父类的,实现代码的复用性;接口更适合做功能的解耦合,解耦合更加灵活。(最佳实现)
九)代码块


  • 类的五大成分:成员变量、构造器、方法、代码块、内部类。
  • 静态代码块:
    (1)格式:static{ }
    (2)特点:类加载时自动执行,由于类只会加载一次,所以静态代码块只执行一次,优先考虑于构造器执行。
    (3)作用:完成类的初始化(如:对静态变量的初始化赋值)。
    (4)import java.util.Arrays:
    System.out.println(Arrays.toString(cards));//返回数组的内容观察
  • 实例代码块
    (1)格式:{ }
    (2)特点:每次创建对象时,执行实例代码块,并在构造器前执行。
    (2)作用:和构造器一样,都是用来完成对象的初始化的(如:对实例变量进行初始化赋值)。
点击查看代码
  1. public class codeBlock {
  2.     public static String NAME;
  3.     public static String[] CARD=new String[54];//初始化数组
  4.     static {//静态代码块,有static修饰,属于类,与类一起优先加载,自动执行一次
  5.         System.out.println("static block");
  6.         NAME="rasion";
  7.         CARD[0]="A";//静态数组只需要初始化一次,就可以在静态代码块中初始化
  8.         CARD[1]="2";
  9.         CARD[2]="3";
  10.     }
  11.     {//实例代码块,没有static修饰,属于对象,与对象一起加载,对象加载几次,就会执行几次
  12.         System.out.println("non-static block");
  13.     }
  14.     public static void main(String[] args) {
  15.         System.out.println("hello main");
  16.         System.out.println(NAME);
  17.         System.out.println(Arrays.toString(CARD));//打印数组
  18.         codeBlock cb=new codeBlock();//创建对象时,会执行实例代码块
  19.         new codeBlock();
  20.         new codeBlock();
  21.         System.out.println(cb);
  22.     }
  23. }
复制代码
十)内部类


  • 当一个类被定义在另一个类内部,则该类称为内部类。
  • 场景:当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。
  • 成员内部类:
    (1)就是类中的一个普通成员,类似前面我们学过的普通的成员变量、成员方法。
    (2)创建成员内部类对象格式:
    外部类名.内部类名 对象名= new 外部类名().new 内部类名();
    Outer.Inter in=new Outer().new Inter();
    (3)成员内部类属于外部类对象持有。
    (4)成员内部类可以直接访问外部类的静态成员、实例成员。
    (5)成员内部类的实例方法中,可以直接拿到当前寄生的外部类对象,格式是:外部类.this.成员名。
点击查看代码
  1. public class main {
  2.     public static void main(String[] args) {
  3.         // 创建成员内部类对象格式:外部类名.内部类名 对象名= new 外部类名().new 内部类名();
  4.         OuterClass.InnerClass innerClass = new OuterClass().new InnerClass();
  5.         innerClass.print();//内部类对象调用内部类方法
  6.     }
  7. }
  8. public class OuterClass {
  9.     //成员内部类:无static修饰,属于外部类的对象持有的
  10.     public class InnerClass{//类有的属性,方法内部类都能有
  11.         private String num="InnerThis";
  12.         public void print(){
  13.             System.out.println("===innerMethod===");
  14.             outerPrint();
  15.             String num="-innerPrint-";
  16.             System.out.println(num);
  17.             System.out.println(this.num);//内部类对象
  18.             System.out.println(OuterClass.this.num);//外部类对象
  19.             OuterClass oc=new OuterClass();//创建外部类对象
  20.             System.out.println(oc.num);
  21.             run();
  22.         }
  23.     }
  24.     //内部类可以访问外部类的静态成员
  25.     public static void outerPrint(){//外部类静态方法
  26.         System.out.println("OuterClass static print");
  27.     }//静态内部类,属于外部类,外部类可以访问
  28.     private String num="OuterThis";//外部类成员变量
  29.     public void run(){}
  30. }
复制代码

  • 静态内部类:
    (1)有static修饰的内部类,属于外部类自己持有。
    (2)创建静态内部类对象格式:
    外部类名.内部类名 对象名= new 外部类名.内部类名();
    Outer.Inner in=new Outer.Inner();
    (3)静态内部类可以直接访问外部类的静态成员;静态内部类不可以直接访问外部类的实例成员。
点击查看代码
  1. public class main {
  2.     public static void main(String[] args) {
  3.         StaticInnerClass.InnerClass innerClass=new StaticInnerClass.InnerClass();//静态内部类对象
  4.         innerClass.print();
  5.     }
  6. }
  7. public class StaticInnerClass {
  8.     public static class InnerClass{
  9.         private String NAME="inner rasion";
  10.         public void print() {
  11.             System.out.println("StaticInnerClass print");
  12.             //静态内部类可以直接访问外部类的静态成员
  13.             System.out.println("StaticInnerClass NAME:"+StaticInnerClass.NAME);
  14.             //静态内部类不可以直接访问外部类的实例成员
  15. //            System.out.println("StaticInnerClass age:"+age);
  16.             //静态内部类可以间接访问外部类的局部变量
  17.             StaticInnerClass staticInnerClass=new StaticInnerClass();
  18.             System.out.println("StaticInnerClass age:"+staticInnerClass.age);
  19.         }
  20.     }
  21.     public static String NAME="outer rasion";//外部类的静态成员
  22.     public int age=18;//外部类的实例成员,属于外部类对象的
  23. }
复制代码

  • 局部内部类:(了解)
    局部内部类:定义在方法中、代码块中、构造器等执行体中(无具体意义,用来引出匿名内部类)。
  • 匿名内部类:
    (1)一种特殊的局部内部类。
    (2)所谓匿名:指的是程序员不需要为这个类声明名字,默认有一个隐藏的名字。
    new 类名或接口(参数值...){
    类体(一般是方法重写);
    };
    new Animal(){
    @Override
    public void cry(){}
    };
    (3)特点:匿名内部类本质是个子类,并且会立即创建出一个子类对象。
    (4)作用:更方便的创建一个子类对象。
    (5)匿名内部类在开发中的常见形式:通常作为一个对象参数传输给方法
    (6)匿名内部类在开发中的真实使用场景示例
    调用别人提供的方法实现需求时,这个方法正好可以让我们传输一个匿名内部类对象给其使用。(开发中不是主动写匿名内部类,而是调用别人的功能时,需要我们写一个匿名内部类)
点击查看代码
  1. public class AnonymityInnerClass {
  2.     public static void main(String[] args) {
  3.     //匿名内部类有名字:外部类名$编号.class
  4.     //匿名内部类本质是一个子类,同时立即创建一个子类对象
  5.         Animal cat=new Animal(){
  6.             @Override
  7.             public void run() {System.out.println("cat run");}
  8.         };//匿名内部类,同cat类,即是一个子类又是一个子类对象
  9. //        Animal cat=() -> System.out.println("cat run");//Lambda简化
  10.         cat.run();
  11.         print(cat);
  12.         
  13.         print(new Animal() {
  14.             @Override
  15.             public void run() {System.out.println("inner cat run");}
  16.         });//同上print(cat);一样功能
  17.     }
  18.     public static void print(Animal animal){
  19.         System.out.println("start==");
  20.         animal.run();//匿名类对象回调,由于匿名类相当于子类,所以可以调用子类的方法
  21.     }
  22. }
  23. interface Animal{
  24.     public abstract void run();
  25. }
  26. //class cat extends Animal{
  27. //    @Override
  28. //    public void run() {
  29. //        System.out.println("cat run");
  30. //    }
  31. //}
复制代码
十一)函数式编程


  • 此“函数”类似于数学中的函数(强调做什么),只要输入的数据一致返回的结果也是一致的
    数学中的函数示例:2x+1
    Java中的函数(Lambda表达式):(x->2x+1)
  • 使用Lambda函数替代某些匿名内部类对象,从而让程序代码更简洁,可读性更好。

  • Lambda表达式
    (1)JDK8新增的一种语法,代表函数。
    (2)可以用于替代并简化函数式接口的匿名内部类,从而让程序更简洁,可读性更好。
    Lambda表达式的格式:(被重写方法的形式参数列表)->{匿名内部类被重写的方法体代码}
    (3)注意:Lambda表达式只能替代函数式接口的匿名内部类!!!
    (4)函数式接口:有且仅有一个抽象方法的接口。
    (5)注意:将来我们见到的大部分函数式接口,上面都可能会有一个@FunctionalInterface的注解,该注解用于约束当前接口必须是函数式接口。
    (6)Lambda表达式的省略规则(用于进一步简化Lambda表达式的写法):
    a、参数类型可以省略不写。
    b、如果只有一个参数,参数类型省略的同时“( )”可以省略,但多个参数不能省略“( )”
    c、如果Lambda只有一行代码,大括号可以省略,同时必须省略分号“;”,如果这行代码是return语句,也必须去掉return。
点击查看代码
  1. public class main {
  2.     public static void main(String[] args) {
  3.         //函数式接口:
  4.         MyInterface myInterface1 = () -> {
  5.             System.out.println("lambda表达式简化匿名内部类");
  6.         };
  7.         myInterface1.print();
  8.         
  9. //public static void sort(T[] a, Comparator<T> c)——————作用:数组按照某个值重排序
  10. //参数一:需要排序的数组   参数二:需要给sort声明一个Comparator比较器对象(指定排序的规则)
  11.         Arrays.sort(students,new Comparator<Student>() {//Comparator为由官方定义的函数式接口
  12.             @Override
  13.             public int compare(Student o1, Student o2) {
  14.                 //如果左边对象大于右边对象,返回正整数,否则返回负整数,等于时为0
  15.                 return o1.getAge()-o2.getAge();//或写成这样,按照年龄升序
  16.             }
  17.         });
  18.         Arrays.sort(students, (o1, o2)-> o1.getAge()-o2.getAge());//以上部分简化后的代码
  19.     }
  20. }
  21. //函数式接口:只有一个抽象方法的接口
  22. @FunctionalInterface//标记函数式接口,编译器会检查,如果接口中有多个抽象方法,编译器会报错
  23. interface MyInterface{
  24. //抽象方法
  25.     public abstract void print();
  26. }
复制代码

  • 方法引用:


  • 静态方法引用
    (1)格式:类名::静态方法名
    (2)使用场景:如果某个Lambda表达式里仅调用了一个静态方法,并且"->"前后的参数形式一致,则可以使用静态方法引用。
点击查看代码
  1. //    Arrays.sort(students, (o1, o2)-> o1.getAge()-o2.getAge());//Student没有加compareByAge方法时
  2.     Arrays.sort(students,(o1, o2)->Student.compareByAge(o1,o2) );//Student加compareByAge方法时可化简,Lambda表达式实现
  3.    
  4.         Arrays.sort(students, Student::compareAge);//静态方法引用简化后的代码
  5. public class Student{
  6.     ...(详见Student类)
  7.     public static int compareByAge(Student o1, Student o2){
  8.         return o1.getAge()-o2.getAge();
  9.     }
  10. }
复制代码

  • 实例方法引用
    (1)格式:对象名::实例方法名
    (2)使用场景:如果某个Lambda表达式里只通过对象名称调用一个实例方法,并且"->"前后的参数形式一致,则可以使用实例方法引用。
点击查看代码
  1. Student t=new Student();//创建一个实例对象
  2.     Arrays.sort(students, (s1,s2) -> t.compareByHeight(s1,s2));//Lambda使用方式
  3.         
  4.     Arrays.sort(students, t::compareByHeight);//实例方法引用
  5.         
  6. public class Student{
  7.     ...(详见Student类)
  8.     public int compareByHeight(Student o1, Student o2){
  9.         //按身高升序排序
  10.         return Double.compare(o1.getHeight(),o2.getHeight());
  11.     }
  12. }
复制代码

  • 特定类的方法引用
    (1)格式:特定类型名称(如:String)::方法名
    (2)使用场景:如果某个Lambda表达式里只调用一个特定类型的实例方法,并且前面参数列表中的第一个参数是作为方法的主调,后面的所有参数都是作为实例方法的入参的,则此时就可以使用特定类型的方法引用。
点击查看代码
  1. Arrays.sort(names, new Comparator<String>() {
  2.     @Override
  3.     public int compare(String o1, String o2) {
  4.         return o1.compareToIgnoreCase(o2);//字符串按照首字母忽略大小写比较的方法
  5.     }
  6. });//匿名内部类的代码
  7. Arrays.sort(names,(o1, o2)-> o1.compareToIgnoreCase(o2));//Lambda简化后的代码
  8.         
  9. Arrays.sort(names,String::compareToIgnoreCase);//特定类的方法引用
复制代码

  • 构造器引用
    (1)格式:类名::new
    (2)使用场景:如果某个Lambda表达式里只是创建对象,并且"->"前后的参数形式一致,则可以使用构造器引用。
点击查看代码
  1. package com.itheima.method1reference;
  2. import jdk.jfr.DataAmount;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. public class Demo4 {
  7.     public static void main(String[] args) {
  8. //        CarFactory cf = new CarFactory() {
  9. //            @Override
  10. //            public Car getCar(String name) {
  11. //                return new Car(name);
  12. //            }
  13. //        };//匿名内部类
  14. //      CarFactory cf= name -> new Car(name);//Lambda代码
  15. //以上两种代码简化后的代码:
  16.         CarFactory cf= Car::new;//构造器引用
  17.         Car c1 = cf.getCar("奔驰");
  18.         System.out.println(c1);
  19.     }
  20. }
  21. @FunctionalInterface
  22. interface CarFactory{
  23.     Car getCar(String name);
  24. }
  25. @Data//封装数据
  26. @AllArgsConstructor//有参构造器
  27. @NoArgsConstructor
  28. class Car{
  29.     private String name;
  30. }
复制代码
十二)常用API(应用程序编程接口)

简单理解:API就是别人写好的东西,我们不需要自己编写,直接使用即可。
Java API:指的就是JDK中提供的各种功能的Java类。

  • String(代表字符串,它的对象可以封装字符串数据,并提供了很多方法完成对字符串的处理)


  • String创建字符串对象的方式
    (1)方式一(推荐):直接“”就可以创建字符串对象,封装字符串数据(java程序中的所有字符串文字(例如”abc“)都为此
    String name="小黑";
    String schoolName="黑马程序员";
    (2)方式二:调用String类的构造器初始化字符串对象。
    (3)只要以”...“方式创建字符串对象,会存储到字符串常量池中,且相同字符串只会储存一份。
    (4)通过 new 方式创建字符串对象,每new一次,都会产生一个新的对象放在堆内存中。
    (5)字符串对象的内容比较,千万不要用,默认比较地址,字符串对象的内容一样时地址不一定一样。
点击查看代码
  1. //方式一(推荐):直接“”就可以创建字符串对象,封装字符串数据
  2. String s1="hello,黑马";//快速创建字符串
  3. System.out.println(s1);//输出hello,黑马而不是地址
  4. //方式二:通过构造器初始化对象。
  5. String s2=new String();//不推荐
  6. System.out.println(s2);//”“空字符串
  7. String s3=new String("hello,黑马");//不推荐
  8. char[] chs={'h','e','l','l',',','黑','马'};
  9. String s4=new String(chars);//把字符数组转换成字符串
  10. byte[] bytes={97,98,99,65,66,67};
  11. String s5=new String(bytes);
  12. System.out.println(s5)
  13. String t1="abc";
  14. String t2="abc";
  15. System.out.println(t1=t2);//字符串在常量池且只有一份,故为true
  16. String t3=new String("abc");
  17. String t4=new String("abc");
  18. System.out.println(s3==s4);//new出字符串对象,故为false
复制代码
构造器说明public String()创建一个空白字符串对象,不含任何内容public String(String original)根据传入的字符串内容,来创建字符串对象public String(char[] chars)根据字符数组的内容,来创建字符串对象public String(byte[] bytes)根据字节数组的内容,来创建字符串对象方法名说明public int length()获取字符串长度返回(字符个数)public char charAt(int index)获取某个索引位置处的字符返回public char[ ] toCharArray()讲当前字符串转换成字符数组返回public boolean equals(Object anObject)判断当前字符串与另一个字符串的内容是否一样,一样返回truepublic boolean equalsIgnoreCase(String anotherString)判断当前字符串与另一个字符串的内容是否一样(忽略大小写)public String substring(int beginIndex,int endIndex)根据开始和结束索引进行截取,得到新的字符串(包前不包后)public String substring(int beginIndex)从传入的索引处截取,截取到末尾,得到新的字符串返回public String replace(CharSequence target,CharSequence replacement)使用新值,讲字符串中的旧值替换,得到新的字符串public boolean containt(CharSequence s)判断字符串中是否包含了某个字符串public boolean startsWith(String prefix)判断字符串是否以某个字符串内容为开头,是则返回truepublic String[ ] split(String regex)把字符串按照某个字符串内容分割,返回字符串数组回来

  • ArrayList
    (1)集合是一种容器,用来装数据的,类似数组,但是容量大小可变,功能丰富,开发中用的更多。
    (2)ArrayList是集合中最常用的一种,ArrayList是泛型类,可以约束存储的数据类型。
    ArrayList list=new ArrayList();
    (3)创建ArrayList对象,代表一个集合容器(调用无参构造器public ArrayList()初始化对象):ArrayList list=new ArrayList();
    (4)创建ArrayList对象时,如果没有用泛型,则调用get方法时返回Object类型的数据。
    (4)调用ArrayList提供的方法,对容器中的数据进行增删改查操作。
    (5)遍历集合:for(int i=0;iError/ (Excetion-->RuntimeException/其他异常)
    (1)Error:代表的系统级别错误(属于严重问题),也就是说系统一旦出问题,sun公司会把这些异常封装成Error对象抛出(Error是给sun公司自己用的,不是给程序员用的,因此我们开发人员不用管他),如:内存溢出、栈溢出等。
    (2)Exception:异常,它代表的才是程序运行过程中出现的问题,程序员通常会用Exception以及它的孩子来封装程序出现的问题。(又分为运行时异常和编译时异常)
    -- 运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现异常(如:数组索引越界异常)。
    -- 编译时异常:编译阶段就会出现错误提醒。(如:日期解析异常、语法错误、类型转换错误等)
  • 异常的基本处理
    (1)抛出异常(throws):在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理。
    (2)捕获异常(try...cath):直接捕获程序出现的异常。
  1. private static void createWindow() {//以下为创建窗口和一个按钮的代码
  2.         JFrame frame = new JFrame("登录窗口");//创建窗口
  3.         JPanel panel = new JPanel();//创建面板
  4.         frame.add(panel);//将面板添加到窗口中
  5.         frame.setSize(300, 200);//设置窗口大小
  6.         frame.setLocationRelativeTo(null);//设置窗口居中
  7.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口默认操作:关闭窗口,推出程序
  8.         JButton button=new JButton("登录");//创建按钮
  9.         //button.setBounds(100,100,80,30);//设置按钮位置和宽高
  10.         panel.add(button);//添加按钮到面板,使按钮能够自适应窗口大小
  11.         frame.setVisible(true);//显示窗口
  12.     }
复制代码
  1. JFrame frame = new JFrame("FlowLayout布局管理器");
  2.   frame.setSize(400, 300);
  3.   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  4.   frame.setLayout(new FlowLayout());//设置窗口的布局管理器对象
  5.   frame.add(new JButton("按钮1"));
  6.   frame.add(new JButton("按钮2"));
  7.   frame.setVisible(true);
复制代码
点击查看代码
  1. JFrame frame = new JFrame("BorderLayout布局管理器");
  2.         frame.setSize(400, 300);
  3.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  4.         frame.setLayout(new BorderLayout());//设置窗口的布局管理器对象
  5.         frame.add(new JButton("按钮1"), BorderLayout.NORTH);
  6.         frame.add(new JButton("按钮2"), BorderLayout.SOUTH);
  7.         frame.add(new JButton("按钮3"), BorderLayout.CENTER);
  8.         frame.add(new JButton("按钮4"), BorderLayout.EAST);
  9.         frame.add(new JButton("按钮5"), BorderLayout.WEST);
  10.         frame.setVisible(true);
复制代码
Ⅱ.异常作用


  • 用来定位程序bug关键信息
  • 可以作为方法内的一种特殊的返回值,以便通知上层调用者,方法的执行出现问题,用来查找bug。
点击查看代码
  1. JFrame frame = new JFrame("GridLayout布局管理器");
  2.         frame.setSize(400, 300);
  3.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  4.         frame.setLayout(new GridLayout(2, 3));//设置窗口的布局管理器对象
  5.         for (int i = 0; i < 6; i++) {
  6.             frame.add(new JButton("按钮" + i));
  7.         }
  8.         frame.setVisible(true);
复制代码
Ⅲ.自定义异常


  • Java无法为全部的问题都提供异常类来代表,企业内部某种问题想通过异常管理,以便用异常来管理问题,需要自定义异常类。
  • 自定义编译异常:
    (1)定义一个异常类继承Exception类。
    (2)并重写构造器。
    (3)通过throw new 异常类(xxx) 创建异常对象并抛出。
    特点:编译阶段就报错,提醒比较激进。
  • 自定义运行时异常:
    (1)定义一个异常类继承RuntimeException类。
    (2)并重写构造器。
    (3)通过throw new 异常类(xxx) 创建异常对象并抛出。
    特点:编译阶段不报错,运行时才可能出现!提醒不属于激进型。
  • 如果想要表达强烈的提醒(他人易犯的错误),就要用编译时异常(少用),若然程序员自己能避免(别人不易犯错),就使用运行时异常(多用)。
点击查看代码
  1. JFrame frame = new JFrame("BoxLayout布局管理器");
  2.         frame.setSize(400, 300);
  3.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  4.         JPanel panel = new JPanel();
  5.         panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));//垂直排列
  6.         panel.add(new JButton("按钮1"));
  7.         panel.add(Box.createVerticalStrut(10));//垂直间距
  8.         panel.add(new JButton("按钮2"));
  9.         panel.add(Box.createVerticalStrut(10));
  10.         panel.add(new JButton("按钮3"));
  11.         frame.add(panel);
  12.         frame.setVisible(true);
复制代码
Ⅳ.异常处理方案


  • 底层异常层层上抛,最外层捕获异常,记录下异常信息,并响应适合用户观看的信息进行提醒。
  • 最外层获取异常后,尝试重新修复。
点击查看代码
  1. JFrame jf=new JFrame("登录窗口");
  2.         JPanel panel=new JPanel();//创建一个面板
  3.         jf.add(panel);//将面板添加到窗口中
  4.         jf.setSize(400,300);//设置窗口大小
  5.         jf.setLocationRelativeTo(null);//设置窗口居中
  6.         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的默认操作:关闭窗口退出程序
  7.         JButton jb=new JButton("登录");//创建一个按钮
  8.         panel.add(jb);//将按钮添加到面板中
  9.         //给按钮绑定点击事件监听对象。
  10.         jb.addActionListener(new ActionListener(){
  11.             @Override
  12.             public void actionPerformed(ActionEvent e){
  13.                 //一旦你点击jb按钮,底层触发这个方法执行
  14.                 //e 是事件对象,封装了事件相关信息
  15.                 JOptionPane.showMessageDialog(jf,"有人点击了登录");
  16.             }
  17.         });
  18.         jf.setVisible(true);//显示窗口
复制代码
(二)泛型

Ⅰ.认识泛型


  • 定义类、方法、接口时,同时声明了一个或多个类型变量(如:< E >)称为泛型类、泛型接口、泛型方法,它们统称为泛型。
  1. JFrame jf=new JFrame("登录窗口");
  2.         JPanel panel=new JPanel();//创建一个面板
  3.         jf.add(panel);//将面板添加到窗口中
  4.         jf.setSize(400,300);//设置窗口大小
  5.         jf.setLocationRelativeTo(null);//设置窗口居中
  6.         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的默认操作:关闭窗口退出程序
  7.         JButton jb=new JButton("登录");//创建一个按钮
  8.         panel.add(jb);//将按钮添加到面板中
  9.         //需求:监听用户键盘上下左右四个按键的事件。
  10.         //给jf窗口整体绑定按键事件。
  11.         jf.addKeyListener(new KeyAdapter() {
  12.             @Override
  13.             public void keyPressed(KeyEvent e){
  14.                 System.out.println("========AAAAAAA========");
  15.                 //获取键盘按键的编码
  16.                 int keyCode=e.getKeyCode();//拿事件源头的键帽编号
  17.                 //判断按键编码是否是上、下、左、右
  18.                 if(keyCode==KeyEvent.VK_UP){
  19.                     System.out.println("用户点击了上");
  20.                 }else if(keyCode== KeyEvent.VK_DOWN){
  21.                     System.out.println("用户点击了下");
  22.                 }else if(keyCode== KeyEvent.VK_LEFT) {
  23.                     System.out.println("用户点击了左");
  24.                 }else if(keyCode== KeyEvent.VK_RIGHT) {
  25.                     System.out.println("用户点击了右");
  26.                 }
  27.             }
  28.         });
  29.         jf.setVisible(true);//显示窗口
  30.         //让窗口成为焦点
  31.         jf.requestFocus();
复制代码

  • 作用:提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力,可以避免强制类型转换,及其有可能出现的异常。
  • 泛型本质:把具体的数据类型作为参数传给类型变量。
Ⅱ.泛型类


  • 基本语法:修饰符 class 类名{ }
  • 注意:类型变量用大写字母,如:T、E、K、V等。
  • 可以控制类接收的类型变量,由于支持多个类型变量,故需注意类型变量的顺序,如:、之类的。
  • 应用场景:在工具类中,经常会有一些方法需要处理不同类型的对象,如集合操作、数据转换等,这时可以使用泛型方法来增强工具类的通用性。
Ⅲ.泛型接口


  • 基本语法:修饰符 interface 接口名{ }
  • 注意:类型变量用大写字母,如:T、E、K、V等。
点击查看代码
  1. package com.itheima.gui;
  2. import javax.swing.*;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. public class Test2 {
  6.     public static void main(String[] args) {
  7.         JFrame jf = new JFrame("登录窗口");
  8.         JPanel panel = new JPanel();//创建一个面板
  9.         jf.add(panel);//将面板添加到窗口中
  10.         jf.setSize(400, 300);//设置窗口大小
  11.         jf.setLocationRelativeTo(null);//设置窗口居中
  12.         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的默认操作:关闭窗口退出程序
  13.         JButton jb = new JButton("登录");//创建一个按钮
  14.         panel.add(jb);//将按钮添加到面板中
  15.         jb.addActionListener(new MyActionListener(jf));
  16.         jf.setVisible(true);
  17.     }
  18. }
  19. //实现类
  20. class MyActionListener implements ActionListener{
  21.     private JFrame jf;
  22.     public MyActionListener(JFrame jf){
  23.         this.jf=jf;
  24.     }
  25.     @Override
  26.     public void actionPerformed(ActionEvent e){
  27.         JOptionPane.showMessageDialog(jf,"有人点击了登录!");
  28.     }
  29. }
复制代码
Ⅳ.泛型方法、通配符、上下限


  • 泛型方法
    修饰符  返回值类型 方法名(形参列表){}
    public static  void test(T t){}
  • 泛型方法作用:泛型方法可以避免强制类型转换,在编译时就能够报错,同时能够确保方法接收参数的多样性,提升方法的复用性。
点击查看代码
  1. JFrame jf=new JFrame("登录窗口");
  2.         JPanel panel=new JPanel();//创建一个面板
  3.         jf.add(panel);//将面板添加到窗口中
  4.         jf.setSize(400,300);//设置窗口大小
  5.         jf.setLocationRelativeTo(null);//设置窗口居中
  6.         jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口的默认操作:关闭窗口退出程序
  7.         JButton jb=new JButton("登录");//创建一个按钮
  8.         panel.add(jb);//将按钮添加到面板中
  9.         //给按钮绑定点击事件监听对象。
  10.         jb.addActionListener(new ActionListener(){
  11.             @Override
  12.             public void actionPerformed(ActionEvent e){
  13.                 //一旦你点击jb按钮,底层触发这个方法执行
  14.                 //e 是事件对象,封装了事件相关信息
  15.                 JOptionPane.showMessageDialog(jf,"有人点击了登录");
  16.             }
  17.         });
  18.         jf.setVisible(true);//显示窗口
复制代码

  • 通配符(wildcard):
    就是“?”,可以在“使用泛型”的时候代表一切类型;ETKV是在定义泛型的时候使用。(通配符是泛型类型的占位符)
  • 泛型的上下限:
    (1)泛型上限:? extends Car表示只能接受Car或者其子类。
    (2)泛型下限:? super Car表示只能接受Car或者其父类。
点击查看代码[code]public class WildcardGeneric {    public static void main(String[] args) {        ArrayList cars = new ArrayList();        cars.add(new Car());        cars.add(new Bmw());        cars.add(new BYD());        run(cars);//输出:汽车在跑\n宝马在跑\n比亚迪在跑        ArrayList bmws = new ArrayList();//        run(bmws);//报错,因为集合里面只能是Car类        bmws.add(new Bmw());        SystemOut(bmws);//输出:BMW    }        public static void run(ArrayList cars){        //这里是虽然是父类,但是只能够访问Car类,不能访问子类,不像多态        for (Car car : cars) {  car.run();  }    }        public static void SystemOut(ArrayList

相关推荐

2025-11-24 23:28:55

举报

您需要登录后才可以回帖 登录 | 立即注册