Java教程

Java SE

本文主要是介绍Java SE,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. Java三大版本

  • JavaSE:标准版,主要应用在桌面程序、控制台开发...
  • JavaME:嵌入式开发,主要应用在手机、小家电...,但是现在应用的不多
  • JavaEE:企业级开发,主要应用在Web端、服务器开发...

2. JDK、JRE、JVM

  • JDK:Java Development Kit,Java开发者工具
    • 包含JRE和JVM
  • JRE:Java Runtime Environment,Java运行时环境
    • 包含JVM,如果只是为了运行Java程序,只需要安装JRE即可
  • JVM:JAVA Virtual Machine,Java虚拟机
    • 运行Java字节码的虚拟机,JVM针对不同的系统有特定的实现(Windows、Linux、MacOS),目的是使用相同的字节码在不同的操作系统中给出相同的结果
      JDK、JRE、JVM

3. Java开发环境搭建

  • JDK下载与安装
    • 下载JDK 8
    • 安装JDK
  • 配置环境变量
    • 添加系统环境变量JAVA_HOME:C:\Program Files\Java\jdk1.8.0_202
    • 添加系统环境变量Path:%JAVA_HOME%\bin、%JAVA_HOME%\jre\bin
  • JDK目录介绍
    • bin:Java可执行程序
    • include:C&C++的头文件
    • jre:Java运行时环境
    • lib:libary,java的类库文件
    • src:资源文件,源代码

4. Java程序运行机制

  • 编译型:先编译再执行
    • 整本书翻译完成后再阅读,如果书内容发生变化需要重新翻译
    • 将代码编译成计算机可识别的
    • 执行速度快
  • 解释型:一遍执行一遍编译
    • 翻译官一遍翻译一遍阅读,如果书内容发生变化即使翻译
    • 一遍运行一遍编译成计算机可识别的
    • 执行速度没有编译型快
  • Java是编译型+解释型的语言
    • 先通过编译器编译成class文件,再通过解释器解释class文件变成计算机可识别的语言
      运行过程
    • 需要格外注意的是 .class->机器码这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了JIT(just-in-time compilation)编译器,而 JIT 属于运行时编译。当 JIT 编译器完成第一次编译后,其会将字节码对应的机器码保存下来,下次可以直接使用。而我们知道,机器码的运行效率肯定是高于 Java 解释器的。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言

著作权归Guide哥所有。
链接: https://javaguide.cn/java/basis/java基础知识总结/#什么是字节码-采用字节码的好处是什么

  • IntelliJ IDEA
    • UserName:lv.feng@outlook.com
    • Password:7u5-8dtabuZZBZq

5. Java基础语法

  • 注释

    • 单行注释
      //程序入口
      public static void main(String[] args){
      
      }
      
    • 多行注释
      /*
      * 程序入口
      * */
      public static void main(String[] args){
      
      }
      
    • 文档注释
      /**
       * @author lvfneg
       * @version jdk1.8
       */
      public static void main(String[] args){
      
      }
      
  • 标识符

    • 关键字:不能使用系统关键字
    • 所有的标识符都应该以字母、美元符、下划线开始
    • 首字母之后可以是字母、美元符、下划线、数字或任何字符组合
    • 不能使用关键字作为变量名或方法名
    • 标识符大小写敏感
    • 可以使用中文命名,但不建议,也不建议使用拼音
  • 数据类型

    • 强类型语言:要求变量的使用严格符合规定,所有变量都必须先定义才能使用
    • 弱类型语言
    • Java的数据类型分为两大类
      • 基本类型(primitive type)
        • 数值类型
          • 整数类型
            • byte:占1个字节,范围-128到127
            • short:占2个字节,范围-3278到32767
            • int:占4个字节,范围-21474838到214748367
            • long:占8个字节,范围-9223372036854775808到9223372036854775807
            //long类型要在数字后加L
            long number = 127L; 
            
            整数扩展
            1、二进制:0B开头
            2、八进制:0开头
            3、十进制:阿拉伯数字
            4、十六进制:0x开头
            
          • 浮点类型
            • float:占4个字节
            • double:占8个字节
            //float类型要在数字后面加F
            float number = 50.1F;
            
            浮点数扩展
            1、float:有限、离散,有舍入误差,实际结果为大约或者接近但不等于
            
          • 字符类型:char占2个字节
            • 所有的字符本质都是数字,通过Unicode进行编码,Unicode表示数字和字符的关联关系
            • 转义字符
              • \t:空格
              • \n:换行
        • boolean类型:占1个字节,只有true和false
          bollean isTrue = true;
          
      • 引用类型(reference type)
        • 接口
        • 数组
      • 什么是字节
        • 位(bit):计算机内部数据存储的最小单位,11001100是一个八位二进制
        • 字节(byte):计算机中数据处理的基本单位,习惯上用大写B来表示
        1B(byte,字节):8bit(位)
        
        • 字符:指计算机中使用的字母、数字、字和符号
        1bit表示1位
        1Byte表示一个字节1B=8b
        1024B=1KB
        1024KB=1M
        1024M=1G
        
  • 类型转换

    • 由于Java是强类型语言,所以要进行有些运算的时候,需要用到类型转换
      低------------------------------------>高
      1、根据存储长度从低到高排序
      2、long比float和double都长,但是排在其后,因为小数优于整数
      byte,short,char->int->long->float->double
      
    • 运算中,不同类型的数据先转换为同一类型,然后进行计算
    • 强制类型转换
      • 由高转到低需要强制转换,由高到底强制转换时容易出现内存溢出的问题(高等级的存储长度超过低等级就会出现内存溢出)
    • 自动类型转换
      • 由低到高自动类型转换

    注意:
    1、不能对boolean值进行转换
    2、不能把对象类型转换为不相干的类型
    3、把高等级转换为低等级时,进行强制转换
    4、转换的时候可能存在内存溢出或者精度问题
    5、操作比较大的数的时候,注意溢出问题 int money=10_0000_0000

  • Java编写规范

    • 类成员变量:首字母小写和驼峰原则,除了第一个单词以外,后面的单词首字母大写
    • 局部变量:首字母小写和驼峰原则
    • 常量:全部大写,可以添加下划线
    • 类名:首字母大写和驼峰原则
    • 方法名:首字母小写和驼峰原则
  • 运算符

    • 算数运算符:+、-、*、/、%、++、--
      • 一元运算符
        • ++、--
        int a = 10;
        //++在后,先赋值再运算
        int b = a++;
        //++再前,先运算再赋值
        int c = ++a;
        
    • 赋值运算符:=
    • 关系运算符:>、<、>=、<=、==、!=
    • 逻辑运算符:&&、||、!
    • 位运算符:&、|、^、~、>>、<<、>>>
      • 效率极高,直接使用二进制,不需要进行转换成二进制
      A = 0011 1100
      B = 0000 1101
      //与运算符,A和B进行比较,如果对应位两个都为1结果为1,反之为0
      A&B:0000 1100
      
      //或运算符,A和B进行比较,如果对应位两个都为0结果为0,反之为1
      A|B:0011 1101
      
      //异或运算符,A和B进行比较,如果对应位相同为结果为0,反之为1
      A^B:0011 0001
      
      //取反运算符
      ~B:1111 0010
      
      //左移、右移
      0000 0000:0
      0000 0001:1
      0000 0010:2
      0000 0011:3
      0000 0100:4
      0000 0101:5
      0000 0110:6
      0000 0111:7
      0000 1000:8
      <<:当前数值*2或者向前进一位 
      >>: 当前数值/2或者向后退一位
      
    • 条件运算符:?:
    • 扩展赋值运算符:+=、-=、*=、/=
  • 包机制

    • 为了更好的组织类,Java提供了包机制,用于区别类名和命名空间
    • 包语句的语法格式
      package pkg1[. pkg2[. pkg3...]]
      
    • 一般利用公司域名倒置作为包名:com.iservice.www,com.iservice.dbhelper
    • 为了能够使用某一个包的成员,需要在Java程序中明确导入该包,使用"import"语句
      //*导入包中的所有类
      import pkg1[. pkg2...].(classname|*)
      
  • JavaDoc

    • javadoc命令是用来生成API文档的
    • 参数信息
      • @author:作者名
      • @version:版本号
      • @since:指明需要最早使用的jdk版本
      • @param:参数名
      • @return:返回值
      • @throws:异常抛出情况
      //生成doc语法,命令行模式
      javadoc -encoding UTF-8 -charset UTF-8 Hello.java
      

6. Java流程控制

  • 用户交互Scanner

    • 通过Scanner工具类,可以获取用户的输入
      //基本语法
      public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("使用next方式接收:");
        //判断用户是否输入字符串
        if(scanner.hasNext()){
            String userInput = scanner.next();
            System.out.println("输入的内容:" + userInput);
        }
        scanner.close();
      }
      
    • 通过Scanner类的next()与nextLine()方法获取输入的字符串,再读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入数据
      • next()
        • 一定要读取到有效字符后才可以结束输入
        • 对输入有效字符之前遇到的空白,next()方法会自动将其去掉
        • 只有输入有效字符后才能将后面输入的空白作为分隔符或者结束符
        • next()不能得到带有空格的字符串
      • nextLine()
        • 以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符
        • 可以获得空格
  • 顺序结构

    • JAVA的基本结构就是顺序结构,除非特别说明,否则就按照顺序一句一句执行
    • 顺序结构是最简单的算法结构
    • 语句与语句之间,框与框之间是按从上到下顺序执行的,它是若干的依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构
  • 选择结构

    • if单选择结构
    • if双选择结构
    • if多选择结构
    • 嵌套的if结构
    • switch多选择结构
      • switch语句中的变量类型可以是
        • byte、short、int或者char
        • 从Java SE7开始,switch支持字符串String类型
        • 同时case标签必须为字符串常量或字面量
  • 循环结构

    • while
    • do...while
    • for
      //死循环
      for(;;){
      
      }
      
    • 在Java5中引入了一种主要用于数组的增强型for循环
      • Java增强for循环语法格式如下
        int[] numbers = {1,2,3,4,5,6};
        for(int x:numbers){
          System.out.println(x);
        }
        
      • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语句块,其值与此时数据元素的值相等
      • 表达式:表达式是要访问的数组名,或者返回值为数组的方法
  • break & continue

    • break:在任何循环语句的主体部分,均可用break控制循环的流程,break用于强行退出循环,不执行循环中剩余的语句
    • continue:用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定
    • 关于goto关键字
      • goto关键字很在就在程序设计语言中出现,尽管goto仍是Java的一个保留字,当并未在语言中得到正式使用,Java没有goto,然而在break和continue这两个关键字身上仍然能看出一些goto的影子,也就是带标签的break和continue
      • 标签:指后面跟着一个冒号的标识符,例如:lable:
      • 对Java来说唯一用到标签的地方是在循环语句之前,而在循环之前设置标签的唯一理由是,我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随同标签使用,他们就会中断到存在标签的地方
        int count = 0;
        outer:for(int i=101;i<150;i++){
          for(int j=2;j<i/2;j++){
            if(i%j==0){
              continue outer;
            }
          }
        }
        

7. 方法详解

  • 何谓方法

    • Java方法是语句的集合,它们在一起执行一个功能
      • 方法是解决一类问题的步骤的有序组合
      • 方法包含在类或对象中
      • 方法在程序中被创建,在其他地方被引用
    • 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合,我们设计方法的时候,最好保持方法的原子性(一个方法只完成一个功能,这样有利于后期的扩展)
  • 方法重载

    • 重载就是在一个类中,有相同的函数名称,但形参不同的函数
    • 重载的规则
      • 方法名称必须相同
      • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同)
      • 方法的返回类型可以相同或不同
      • 仅仅返回类型不同不足以成为方法的重载
    • 实现理论
      • 方法名称相同时,编译器会根据调用方法的参数个数、类型等去逐个匹配,以选择对应的方法,如果匹配失败编译器会报错
  • 命令行传参

    • 运行一个程序时传递给他消息,这要靠传递命令行参数给main()函数实现
  • 可变传参

    • JDK5开始,Java支持传递同类型的可变参数给一个方法
    • 在方法声明中,在指定参数类型后加一个省略号(...)
    • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明
  • 方法的调用

    • 静态方法
    • 非静态方法
    • 形参和实参
    • 值传递和引用传递
    • this关键字

8. 数组

  • 数组概述

    • 一组相同类型数据的有序集合
    • 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合
    • 其中,每一个数据称作为一个数组元素,每个数组元素可以通过一个下标来访问它们
  • 数组声明&创建

    • 数组的默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化
    //声明
    int[] numbers;
    int numbers[];
    //创建
    int[] numbers = new int[10];
    int[] numbers = new int[]{1,2,3,4,5};
    //获取数组长度
    int count = numbers.length;
    
    • 数组的四个基本特别
      • 长度确定,一旦创建大小不可被改变
      • 其元素必须是相同的类型
      • 数组中的元素可以是任何数据类型,包括基本类型和引用类型
      • 数组变量属于引用类型,数组可以看成是一个对象,数组中的每个元素相当于该对象的成员变量
      • 数组本身就是对象,Java的对象是在堆中,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的
  • 内存分析

    • Java内存分析
        • 存放new的对象和数组
        • 可以被所有的线程共享,不会存放别的对象引用
        • 存放基本变量类型(包含这个基本类型的具体数值)
        • 引用对象的变量(会存放这个引用在堆里面的具体地址)
      • 方法区
        • 可以被所有的线程共享
        • 包含了所有的class和static变量
  • 数组使用

    • for循环
    • For-Each
      int[] numbers = {1,2,3,4,5};
      for(int i : numbers){
        System.out.println(i);
      }
      
    • 数组作为方法入参
    • 数组作为返回值
  • 多维数组

    • 多维数组可以堪称数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
    • 二维数组
      //数组a可以看成一个两行五列的数组
      int a[][] = new int[2][5];
      //数组b可以看成一个两行三列的数组
      int b[][] = {{1,2},{3,4},{5,6}};
      
  • Arrays类

    • 数组帮助类
  • 稀疏数组

    • 定义
      • 当一个数组中的大部分元素为0或者为同一值的数组时,可以使用稀疏数组来保存该数组
    • 稀疏数组的处理方式
      • 记录数组一个共几行几列,有多少个不同值
      • 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
    • 如下图,左边是原始数组,右边是稀疏数组
      稀疏数组

9. 面向对象编程-OOP

  • 初始面向对象

    • 类是对事务的一中抽象,对象是一个具体的实例
  • 面向对象三大特性

    • 封装
      • 程序设计要求高内聚、低耦合,高内聚就是类的内部数据操作细节自己完成,不允许外部干涉,低耦合就是仅暴露少量的方法给外部使用
      • 优点
        • 提高程序的安全性,保护数据
        • 隐藏代码的实现细节
        • 统一接口
        • 提高系统的可维护性
    • 继承
      • 集成的本质是对某一批类的抽象,从而实现对现实世界更好的建模
      • extends的意思是”扩展“,子类是父类的扩展
      • JAVA中只有单继承,没有多继承
      • 继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等
      • 继承关系的两个类,一个为子类(派生类),一个为父类(基类),子类继承父类,使用关键字extends来表示
      • 子类和父类之间,从意义上讲应该具有"is a"的关系
      • object:所有类的父类
      • 被final修饰的类不能被继承
        /*
          Ctrl+H 可以查看类的继承关系
          Alt+Insert 快速创建构造、属性方法
          Ctrl+Alt+点击鼠标 跳转至实现
        */
        public class Person{
          public void say(){
            System.out.println("Hello World")
          }
        }
        
        public class Chinese extends Person{
        
        }
        
        public static void main(String[] args){
          new Chinese().save();
        }
        
      • super/this
        • 调用本类&父类的构造器,必须放在第一行
        public class Person(){
          protected String name="parent";
        }
        public class Chinese extends Person{
          private String name="lvfeng";
          public void test(string name){
            //方法的参数
            System.out.println(name)
            //当前类的字段
            System.out.println(this.name)
            //父类的字段
            System.out.println(super.name)
          }
        }
        
      • 方法重写
        • 只能重写非静态的public方法
        public class Person(){
          public void say(){
            System.out.println("Hello World")
          }
        }
        public class Chinese extends Person{
          @override
          public void say(){
            System.out.println("Hello World")
          }
        }
        
    • 多态
    • instanceof
      • 引用类型转换
      if(chinese instanceof person){
        return "父子关系";
      }
      
  • 代码块

    {
      /*
        匿名代码块:在静态代码块之后构造函数之前执行
      */
    }
    
    static {
      /*
        静态代码块:构造函数之前执行且只执行一次
      */
    }
    
    //静态导入包
    import static java.lang.Math.random;
    public static void main(String[] args){
      System.out.println(random());
    }
    
  • 抽象类

    • abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法该方法为抽象方法,如果修饰类该类为抽象类
    • 抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类
    • 抽象类不能使用new关键字来创建它,它是用来让子类继承的
    • 抽象方法只有方法的声明,没有方法的实现,它使用子类来实现的
    • 子类继承抽象类,必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
      public abstract class Action{
        public abstract void go();
      }
      
      public class Child extends Action{
        @override
        public void go(){
      
        }
      }
      
      public abstract class Child2 extends Action{
        public abstract void go();
        public void run(){
          System.out.println("Hello World");
        }
      }
      
      public static void main(String[] agrs){
        Action action = new Child();
        action.go();
      }
      
  • 接口

    • 接口就是规范,定义的是一组规则或者约束
    • 接口的本质就是契约,就像法律一样,制定好了大家一起遵守
    • OO的精髓,是对对象的抽象,最能体现这一点的就是接口
    • 接口中所有的定义其实都是抽象的public abstract
    • 实现了接口的类,必须实现接口中的所有方法
      public interface IAction{
        //静态常量:public static final
        int AGE=99;
        void go();
      }
      
      public interface IAction1{
        void run();
      }
      public class Action implements IAction,IAction1 {
        @override
        public void go(){
          System.out.println("Hello World");
        }
      
        @override
        public void run(){
          System.out.println("Hello World");
        }
      }
      

10. 异常

  • 异常体系结构

    • 检查性异常:用户错误或问题引起的异常,程序无法预见的,例如打开一个不存在的文件
    • 运行时异常:运行时异常可能被程序员避免的异常,与检查性异常相反,运行时异常可以在编译时被忽略
    • 错误:错误不是异常,是脱离程序控制的问题,错误在代码中通常被忽略,例如当栈溢出时一个错误就发生了,它们在编译也检查不到
    • Java把异常当作对象来处理,并定义了一个基类java.lang.Throwable作为所有异常的基类
    • 在Java中已经定义了很多异常类,这些异常类分为两大类,错误Error和异常Exception
      • Error
        • Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
        • Java虚拟机运行错误(Virtual MachineError),当JVM不在有继续执行操作所需的内存资源时将出现OutOfmemoryError,这些异常发生时,Java虚拟机一般会选择线程终止
        • 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError),这些错误时不可查的,因为他们在应用程序的控制和处理能力之外,而且绝大多数时程序运行时不允许出现的状况
      • Exception
        • 在Exception分支中有一个重要的子类RuntimeException(运行时异常)
        • 这些异常一般是由程序逻辑错误引起的
      • Error和Exception
        • Error通常时灾难性的致命错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机一般会选择终止线程
        • Exception通常情况下是可以被程序处理的,并在程序中应该尽可能的去处理这些异常
  • Java异常处理机制

    • 抛出异常
    • 抓取异常
  • 处理异常

    • 异常处理的五个关键字
    • try catch finally throw throws
      • throw:主动抛出异常
      public void scal(){
        int a = 10
        int b = 0;
        if(b==0){
          throw new ArithmeticException();
        }
      }
      
      • throws:向上跑异常,在上层处理异常
      public void scal() throws ArithmeticException{
        int a = 10;
        int b = 0;
        int c = a / b;
      }
      
    • 捕获多个异常,编写catch时需要从小到达编写
    • Ctrl+Alt+T 快速生成异常捕获块
  • 自定义异常

    • Java内置的异常类可以描述在编程时出现的大部分异常情况,除此之外,用户还可以自定义异常,用户自定义异常,只需要继承Exception类即可
    • 在程序中使用自定义异常,可以分为以下步骤
      • 创建自定义异常类
      • 在方法中通过throw关键字抛出异常对象
      • 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作
      • 在出现异常方法的调用者中捕获并处理异常
    public class MyException extends Exception{
      private int _numbers;
      public MyException(int numbers){
        _numbers = numbers;
      }
      @override
      public String toString(){
        return "MyException{"+_numbers+"}";
      }
    }
    

11. Java常用类

  • 内部类

    • 定义
      • 在一个类的内部再定义一个完整的类
      • 一个Java类中可以有多个同等级的class类,但只能有一个public class
    • 特点
      • 编译之后可生成独立的字节码文件
      • 内部类可直接访问外部类的私有成员
      • 可为外部类提供必要的内部功能组件
    • 成员内部类
      • 定义:再类的内部定义,与实例变量、方法同级别
      • 外部类的一个实列部分
      • 当外部类和内部类属性出现重名时,优先使用内部类的属性
      • 成员内部类不能定义静态成员
      • 成员内部类可以包含静态常量 final
        public class Outer{
          private String name;
          private int age;
        
          class Inner{
            private String name;
            private String address;
            private String phone;
            public void show(){
              //打印内部类的name,如果内部类没有这个成员直接访问的外部类
              System.out.println(name);
              //当出现重名时,使用如下方式调用外部类的属性
              System.out.println(Outer.this.name);
            }
          }
        }
        
        public static void main(String[] args){
          Outer outer = new Outer();
          Inner inner = outer.new Inner();
          Inner inner = new Outer().new Inner();
          inner.show();
        }
        
    • 静态内部类
      • 定义:
        • 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员,相当于一个外部类,他的级别和外部类相同
        • 静态内部类不能直接使用外部类的属性,只能通过New的方式进行获取或者将外部类的属性设置成静态的,因为静态内部类的创建比外部类的非静态属性要早,所以静态内部类拿不到
        public class Outer{
          private String name;
          private int age;
        
          static class Inner{
            private String address;
            private String phone;
            private static int count;
            public void show(){
              Outer outer = new Outer();
              System.out.println(outer.name);
        
              //访问静态内部类非静态成员
              System.out.println(phone);
              //访问静态内部类静态成员
              System.out.println(Inner.count);
            }
          }
        }
        
        public static void main(String[] args){
          Outer.Inner inner = new Outer.Inner();
          inner.show();
        }
        
    • 局部内部类
      • 定义:定义在外部类的方法当中,作用范围和创建对象的范围仅限于当前方法
      • 局部内部类不能使用访问修饰符
      • 局部内部类不能使用静态属性,但是可以使用静态常量 final static
      • 局部内部类访问外部类方法中的局部变量时,因为无法保证变量的生命周期与自身相同,变量必须修饰为final,但是在jdk1.8后不需要添加final修饰符,因为jdk1.8默认添加了
        public class Outer{
          private String name;
          private int age;
          public void show(){
            String address;
        
            //定义局部内部类
            class Inner{
              private String phone;
              private String email;
              public void show2(){
                //访问外部类属性
                System.out.println(name);
                //访问内部类属性
                System.out.println(phone);
                //访问外部方法的属性,jdk1.7要求变量必须是常量,jdk1.8自动添加final
                System.out.println(address);
              }
            }
        
            Inner inner = new Inner();
            inner.show();
          }
        }
        public static void main(String[] args){
          new Outer().show();
        }
        
    • 匿名内部类
      • 定义:没有类名的局部内部类(一切特征都与局部内部类相同)
      • 必须继承一个父类或者实现一个接口
      • 定义类、实现类、创建对象的语法合并,只能创建一个类的对象
      • 优点:减少代码量
      • 缺点:可读性差
        public interface IOuter{
          void service();
        }
        public static void main(String[] args){
          //局部内部类
          class Inner implements IOuter{
            @override
            public void service(){
              System.out.println("Hello World");
            }
          }
          IOuter outer = new Inner();
          outer.service();
        
          //匿名内部类
          IOuter outer = new IOuter(){
            @override
            public void service(){
              System.out.println("Hello World");
            }
          }
          outer.service();
        }
        
  • Object

    • 定义
      • 超类、基类,所有类的直接或间接父类,位于继承树的最顶层
      • 任何类,如没有书写extends显示继承某个类,都默认直接继承object,否则为间接继承
      • Object类中所定义的方法,是所有对象都具备的方法
      • Object类型可以存储任何对象
        • 作为参数,可接收任何对象
        • 作为返回值,可返回任何对象
    • 常用方法
      • getClass
        • 返回:Class
        • 定义:返回引用中存储的实际对象类型
        • 应用:通常用于判断两个引用中实际存储的对象是否一致
        public class Student{
          public String name;
          public int age;
        }
        public static void main(String[] args){
          Student stu1 = new Student();
          Student stu2 = new Student();
          //判断stu1和stu2是否同一类型
          Class c1 = stu1.getClass();
          Class c2 = stu2.getClass();
          if(c1 == c2){
            return true;
          }else{
            return false;
          }
        }
        
      • hashCode
        • 返回:int
        • 定义
          • 返回该对象的哈希码值
          • 哈希值根据对象的地址或字符串或数字使用hash算法计算出来的int类型的数值
        • 一般情况下相同对象返回相同的哈希码
        • 应用:判断对象的内存地址是否相同
        public class Student{
          public String name;
          public int age;
        }
        public static void main(String[] args){
          Student stu1 = new Student();
          Student stu2 = new Student();
          int stu1 = stu1.hashCode();
          int stu2 = stu2.hashCode();
          if(stu1 == stu2){
            return true;
          }else{
            return false;
          }
        }
        
      • toString
        • 返回:String
        • 定义
          • 返回对象的字符串表示(表现形式)
          • 可以根据程序需求覆盖方法,如:展示对象各个属性值
        public class Student{
          private String name;
        
          //重写Object的toString()
          @override
          public String toString(){
            return "Hello World";
          }
        }
        public static void main(String[] args){
          //返回对象的全名称+@+hashCode(16进制)
          String stu1 = stu1.toString();
          String stu2 = stu2.toString();
        }
        
      • equals
        • 返回:boolean
        • 定义
          • 比较两个对象地址是否相同
          • 可进行重写,比较两个对象的内容是否相同
        • equals和==的区别
          • 基本数据类型:==比较值
          • 引用数据类型:==比较的是对象的内存地址
          • 因为Java只有值传递,对于==来说,不管是比较基本数据类型还是引用数据类型,其本质比较的都是值,只是引用类型变量存的值是对象的地址
          • equals不能用于判断基本数据类型的变量,只能判断两个对象是否相等
        public class Student{
          private String name;
        
          @override
          public boolean equals(Object obj){
            if(this == obj){
              return true;
            }
            if(obj == null){
              return false;
            }
            //判断对象的类型是否相同
            <!-- if(this.getClass() == obj.getClass()){
              return true;
            } -->
            if(obj instanceof Student){
              Student stu = (Student)obj;
              if(this.name == stu.name){
                return true;
              }
            }
            return false;
          }
        }
        public static void main(String[] args){
          Student stu1 = new Student();
          Student stu2 = new Student();
          System.out.println(stu1.equals(stu2));
        }
        
      • finalize
        • 当对象判定为垃圾对象时,由JVM自动调用此方法,用以标记垃圾对象,进入回收队列
        • 垃圾对象:没有有效引用指向此对象时
        • 垃圾回收:由GC销毁垃圾对象,释放数据存储空间
        • 自动回收机制:JVM内存耗尽,一次性回收所有对象
        • 手动回收机制:使用System.gc()通知JVM执行垃圾回收
        public class Hello{
          @override
          protected void finalize() throws Throwable{
            System.out.println("对象堆GC回收了");
          }
        }
        public static void main(String[] args){
          Hello hello = new Hello();
          //垃圾回收,执行此语句没有执行对象的finalize
          System.gc();
          
          new Hello();
          //垃圾回收,执行此语句执行了对象的finalize
          System.gc();
        }
        
  • 包装类

    • 定义
      • 基本数据类型所对应的引用数据类型
      • 基本数据类型只能操作运算符,没有Object对应的方法,包装类就是基本数据类型所对应的引用数据类型,可以让基本数据类型使用Object对应的方法
      • 完整的定义就是把基本数据类型包装成一个对象,使其变成一个引用类型,存放数据时也会从栈存放到堆中
    • Object可统一所有数据,包装类的默认值是null
    • 基本数据类型对应的引用类型
      • byte:Byte
      • short:Short
      • int:Integer
      • long:Long
      • float:Float
      • double:Double
      • boolean:Boolean
      • char:Char
  • 类型转换与装箱、拆箱

    • 基本数据类型:存放在栈中
    • 引用数据类型:存放在堆中
    • 装箱:基本数据类型转换成引用数据类型,数据由栈存放在堆中
    • 拆箱:引用数据类型转换成基本数据类型,数据由堆存放在栈中
      /*
        JDK1.5之前
      */
      //装箱
      int num = 18;
      Integer i1 = new Integer(num);
      Integer i2 = Integer.valueOf(num);
      //拆箱
      num = i1.intValue();
      
      /*
        JDK1.5之后,提供自动装箱和拆箱
      */
      //装箱
      Integer i1 = num;
      //拆箱
      num = i1;
      
  • 整数缓冲区

    • Java预算创建了256个常用的整数包装类型对象
    • 在实际应用中,对已创建的对象进行服用
    • 整数缓冲区范围-128——127
      Integer i1 = new Integer(100);
      Integer i2 = new Integer(100);
      //当前结果返回false,因为Integer是引用类型,i1和i2的内存引用不同
      System.out.println(i1 == i2);
      
      Integer i1 = 100; // 等同于 Integer i1 = Integer.valueOf(100);
      Integer i2 = 100;
      
      //当前结果返回true,因为上面的代码执行了自动装箱(valueOf)的操作,valueOf会从缓存中读取-127到128的数值,因为之前已经实例化,所以i1和i2的内存指向相同
      System.out.println(i1 == i2);
      
      Integer i1 = 200;
      Integer i2 = 200;
      //当前结果返回false,即使走的也是valueOf方法,但200已经超过了整数缓冲区,所以会执行new Integer()重新创建一个新的对象
      System.out.println(i1 == i2);
      
  • String类

    • 字符串是常量,创建之后不可改变
    • 字符串字面值存储在字符串池中,可以共享,字符串在方法区中
      • Java内存存放区域类型
        • 堆:存放引用类型
        • 栈:存放基本类型
        • 方法区:类、方法、静态变量+常量、字符串池
      /*
        产生一个对象,字符串池中存储
        创建流程:先在栈开辟空间,然后判断字符串池中是否有Hello,如果有返回内存地址,反之则创建后返回地址
      */
      String str = "Hello";
      
      /*
        产生两个对象,堆、池各存储一个
        创建流程:先在栈中开辟空间,然后判断字符串池中是否有Hello,如果有不进行任何操作,反之则开辟空间,最后在堆中开辟空间创建空对象,但是堆中的内存地址是字符串中的地址,然后将堆中的地址返回回去
      */
      String str = new String("Hello");
      
    • 可变字符串
      • StringBuffer:可变长字符串,JDK1.0提供,运行效率慢,线程安全
      • StringBuilder:可变长字符串,JDK5.0提供,运行效率快,线程不安全
      • 与String的区别
        • 效率比String高
        • 比String节省内存
      StringBuffer sb = new StringBuffer();
      sb.append("追加字符串");
      System.out.println(sb.toString());
      
      StringBuilder sb = new StringBuilder();
      sb.append("追加字符串");
      System.out.println(sb.toString());
      
      //验证StringBuilder效率高于StringBuffer
      long start = System.CurrentTimeMillis();
      String string="";
      for(int i=0;i<99999;i++){
        string+=i;
      }
      long end = System.CurrentTimeMillis();
      System.out.println("用时:"+(end-start));
      
      long start = System.CurrentTimeMillis();
      StringBuffer string = new StringBuffer();
      for(int i=0;i<99999;i++){
        string.append(i);
      }
      long end = System.CurrentTimeMillis();
      System.out.println("用时:"+(end-start));
      
      long start = System.CurrentTimeMillis();
      StringBuilder string = new StringBuilder();
      for(int i=0;i<99999;i++){
        string.append(i);
      }
      long end = System.CurrentTimeMillis();
      System.out.println("用时:"+(end-start));
      
  • BigDecimal类

    • double和float:近似值存储,在进行运算时会有偏差
    • 在要求精度准确的情况下需要借助BigDecimal
      //double和float在内存中存放的是一个近似值,所以计算出来的结果会有偏差
      double d1 = 1.0;
      double d2 = 0.9;
      //d3并不等于0.1,而是0.999999998
      double d3 = d1 - d2;
      
      BigDecimal n1 = new BigDecimal("1.0");
      BigDecimal n2 = new BigDecimal("0.9");
      //执行减法
      BigDecimal n3 = n1.subtract(n2);
      /*
        加法:add
        乘法:multiply
        除法:devide
      */
      
  • Date

    • Date表示特定的瞬间,精确到毫秒。Date类中的大部分方法都已经被Calendar类中的方法所取代
  • Calendar

    • 提供了获取和设置各种日历字段的方法
    • 构造方法:protected Calendar():由于修饰符是protected,所以无法直接创建该对象
      //创建对象
      Calendar calendar = Calendar.getInstance();
      
  • SimpleDateFormart

    • SimpleDateFormart是一个以与语言环境有关的方式来格式化和解析日期的具体类
    • 进行格式化(日期转文本),解析(文本转日期)
      SimpleDateFormart sdf = new SimpleDateFormart("yyyy-MM-dd HH:mm:ss");
      Date date = new Date();
      String d = sdf.formart(date);
      
  • System

    • 系统类,主要用于获取系统的属性数据和其他操作,构造方法私有

12. 集合框架

  • 概念

    • 对象的容器,定义了多个对象进行操作的常用方法,可实现数组的功能
    • 和数组的区别
      • 数组长度固定,集合长度不固定
      • 数组可以存储基本类型和引用类型,集合只能存储引用类型
      • 如果向集合中添加基本数据类型,将会自动完成装箱,生成基本类型的对应包装类
  • Collection体系集合

    Collection
    • 特点
      • 层次结构的跟接口
      • 代表一组任意类型的对象,无序、无下标、不能重复
    • 常用方法
      • add:添加一个对象到集合中
      • addAll:将一个集合的所有对象添加到此集合中
      • clear:清空集合的所有对象
      • contains:检查集合中是否包含对象
      • equals:比较集合是否与指定对象相等
      • isEmpty:判断集合是否为空
      • remove:移除集合中的指定对象
      • size:返回集合中元素的数量
      • toArray:将集合转换成数组
      • iterator:返回在此集合的元素进行迭代的迭代器
      Collection collection = new ArrayList();
      
      collection.add("Hello");
      collection.remove("Hello");
      collection.clear();
      collection.size();
      
      for(Object obj : collection){
        System.out.println(obj);
      }
      //在迭代过程中不允许使用Collection移除方法
      Iterator item = collection.iterator();
      while(item.hasNext()){
        item.remove();
        System.out.println(item.next());
      }
      
      collection.contains("Hello");
      
  • List

    • 特点:有序、有下标、元素可以重复
    • 继承Collection所有的迭代器,但是List有自己的迭代器ListIterator
      • ListIterator:列表迭代器,允许程序员按任意方向遍历列表,迭代期间可添加、修改、删除元素
      List list = new ArrayList();
      list.add("Hello");
      ListIterator iterator = list.listIterator();
      //从前往后
      while(iterator.hasNext()){
        int index = iterator.nextIndex();
        Object item = iterator.next();
      }
      
      //从后往前
      while(iterator.hasNext()){
        int index = iterator.previousIndex();
        Object item = iterator.previous();
      }
      
    • List实现类
      • ArrayList
        • 数组结构实现,查询快、增删慢
        • JDK1.2版本,运行效率快,线程不安全
        • 特点
          • 向集合中添加元素后默认容量为10,没有向集合中添加元素默认容量为0
          • elmentData:存放元素的数组
          • add:
        ArrayList arrayList = new ArrayList();
        Iterator iterator = arrayList.iterator();
        while(iterator.hasNext()){
          System.out.println(iterator.next());
        }
        
        ListIterator iterator = arrayList.listIterator();
        while(iterator.hasNext()){
          System.out.println(iterator.next());
        }
        while(iterator.hasPrevious()){
          System.out.println(iterator.previous());
        }
        
      • Vector
        • 数组结构实现,查询快、增删慢
        • JDK1.0版本,运行效率慢、线程安全
      • LinkedList
        • 链表结构实现,增删快、查询慢
  • 泛型

    • 概念
    • 泛型类
    • 泛型接口
    • 泛型方法
    • 方法集合
  • Set

  • HashSet

  • TreeSet

  • Map

  • HashMap

  • TreeMap

  • Collection工具类

13. I/O

14. 多线程

15. 网络编程

16. GUI编程

17. 注解和反射

18. JUC并发编程

19. JVM升入研究

这篇关于Java SE的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!