前言

​ 由于面临找工作困境,结合大环境和自身分析,暂定目标岗位为java后端开发,因此快速学习一下java基础语法。

基础语法

  1. 数据类型包括基本数据类型和引用数据类型,强制转换使用小括号
  2. 引用数据类型就是可以被引用的数据类型,包括字符串、

面对对象

内存

  1. Java中的存储空间,栈中间储存函数和变量,堆中储存对象,元空间储存类的信息。
  2. 堆中保存的是实例对象的成员属性,元空间中储存的是类的静态属性。
  3. 先有类再有对象,因此成员函数中可以调用静态函数,但是静态函数不允许调用成员函数
  4. 类的信息加载完成后,会自动调用静态代码块,可以完成静态属性的初始化功能

  1. 包,容纳类,主要用于功能分类,包含上下级关系
  2. 创建对象时,可以使用类的相对路径来准确调用

继承与多态

  1. 继承 Extends
  2. 类的继承只能单继承,只能有一个父类,不能有多个父类
  3. super和this 分别表示调用父类的成员变量和子类的成员变量
  4. 对于一个父类,创建子类n次,那么父类也需要相对应的创建n次,每个不同的子类对应的父类对象不一样
  5. 多态,一个对象在不同场景下表现出来的不同状态,但是对使用场景进行了约束

重写与重载

  1. 方法名相同、参数列表不相同,会认为是不同的方法,这就是重载
  2. 如果子类对象需要在特殊场合使用父类方法,那么就需要重写方法,重写要求子类和父类的方法名字相同,返回值类型相同,参数列表相同。

枚举

  1. 枚举是特殊的类,包含特定对象,且对象不会改变,使用关键字enum,对象一般是用大写标识符
  2. 枚举可以使用构造函数进行构造,枚举类会将对象放置在对前面
  3. 枚举类不能创建对象,他的对象是在内部自行创建

匿名类

  1. 匿名类,在一些场合,类的名字不重要,主要是使用类的方法或者功能,因此可以使用匿名类,
  2. 使用匿名类,减少重复操作,接口也可以使用匿名类,具体实现就是在创建对象的时候直接实现抽象类中的方法即可
  3. Bean类的设计规范,必须含有无参、公共的构造方法,属性必须私有化,然后提供公共的set、get方法

常见类和对象

Object

  1. toString()默认打印对象的内存地址,输出的是十六进制,也可以使用hashCode(),输出结果十进制

  2. equals() 判断两个对象是否相等,比较对象的时候,默认比较的是内容地址

  3. getSimplename() 获取对象的类型信息

数组

  1. <类型> [] <名称>= new <类型>[size] ;
  2. Boolean 类型数组 默认值是falseObject数组和字符串数组默认值是NULL
  3. java中按值传递指的是在调用参数的时候,将实际参数复制一份传递到函数中,这样在函数中对参数进行修改,不会影响到原来的实际参数
  4. 引用传递指的是将实际参数的地址直接传递到函数中,函数对参数的修改会影响原来的实际参数
  5. 一般来说,对于基础数据类型变量,使用按值传递,对于对象变量,使用的是引用传递。但是实际上二者本质相同,区别就是基础数据类型变量的值是数字和布尔值,而对象引用变量的值是对象的地址。

字符串

  1. 字符串是连续的字符组成的整体

  2. 字符可以使用ASCII码来表示字符,ASCII码使用一个字节表示。

  3. java使用new构造字符串和直接赋值字符串的方式在底层实现不同。

  4. 连续的字符数组可以转换为字符串

    char cs ={'a','b','b'};
    String s = new String(cs);
  5. 字符串拼接相当于创建新的字符串,并且新的字符串与原来的字符串内存地址不一样。

  6. 字符串的比较,采用Object中比较的成员方法a.equals(b)

  7. 字符串的截取,s.substr(straIndex,endIndex),不包含最后的索引

  8. 字符串的截取,s.split()

  9. 字符串的去空格,s.strim(),去除字符串的首尾空格

  10. 字符串的替换,s.replace()或者s.replaceAll()

  11. 字符串的大小写转换 s.toLowerCase() 或者 s.toUpperCase()

  12. 字符串的查找 s.charAt(i);

  13. 使用StringBuilder对字符串进行拼接,本质上是使用底层数组完成字符串的拼接

    StringBuilder s = new StringBuilder();
    for(int i=0;i<100;++i){
    s.append(i);
    }
    System.out.println(s.toString());

引用数据类型

  1. 内置的八种数据类型 byte、short、int、long、float、double、char、boolean并没有对应的属性和方法,因此可以将其进行扩展,使用包装类来实现更多的功能。
  2. 自动装箱和自动拆箱
  3. 日期类与日历类的使用
  4. 工具类不应该创建对象才能使用,这也就意味着可以直接使用类中的属性和方法,一般都声明为静态的
  5. 工具类对外提供的属性或者方法都应该是公共的
  6. hashcode()主要是获得对象散列地址,并非实际的内存地址,因此hashcode()相等无法证明两个对象为同一个对象,因此使用System.identityHashCode() 查看实际的内存地址
  7. Integer类中提前将(-128,127)储存到caffe中,因此当数值相同时,即使对象不同,其内存地址也是相等的
  8. 对于引用类型的比较,都需要使用equals()进行比较,使用==比较的是对象的内存地址

异常

  1. 异常分为两类,可以通过代码恢复正常逻辑执行的异常(运行期异常)、不能通过恢复代码恢复的异常(编译器异常),前者是RuntimeException(),后者是Exception()

  2. 错误不是异常,是与异常并列的。Error()

  3. 异常处理语法,和swich()比较相似

    try{
    //可能会出现的异常的代码
    //如果出现异常,那么JVM会将异常进行封装,形成一个具体的异常类,然后将这个异常抛出
    //所有异常对象都可以被抛出
    }catch(/*抛出的异常对象,对象引用*/){
    //异常的解决方案
    }finally{
    //最终执行的代码逻辑
    }
  4. 如果方法中可能会出现问题,那么需要提前声明,此时就需要关键字throws。如果需要手动抛出异常对象,那么需要使用throw关键字,然后new出异常

集合

  1. 集合可以分为单一数据体系和成对出现的数据体系
  2. Collection接口中常用的子接口包括List、Set、Queue,其中List的具体实现包括ArrayListLinked List,Set的具体实现类包括 HashsetQueuen的具体实现类包括 ArrayBlockingQueue
  3. Map接口中常用的具体实现包括HashMapHashTable

ArrayList

  1. 增加数据 add(value)
  2. 获取指定位置的数据,采用索引方式 get(index)
  3. 修改指定位置数据 set(index,value)
  4. 删除数据 remove(index)
  5. 扩容机制:ArrayList底层是数组实现,扩容可以分为两种情况
    1. ArrayList容量是0的时候,此时添加元素需要扩容,不同的构造方法对应不同的扩容策略:
      1. 无参构造,创建ArrayList后容量为0,添加第一个元素后,容量变为10,此后若需要扩容,则正常扩容。
      2. 传容量构造,当参数为0时,创建ArrayList后容量为0,添加第一个元素后,容量为1,此时ArrayList是满的,下次添加元素时需正常扩容。
      3. 传列表构造,当列表为空时,创建ArrayList后容量为0,添加第一个元素后,容量为1,此时ArrayList是满的,下次添加元素时需正常扩容。
    2. ArrayList的容量大于0,并且ArrayList是满的时,此时添加元素的话,进行正常扩容,每次扩容到原来的1.5倍。
  6. 插入参数 add(index,value)
  7. 添加集合 add(list)
  8. 获取数据在数据中的索引号 indexOf(value)

LinkedList

  1. 添加元素 add()
  2. 在头部添加元素 addFirst()
  3. 在尾部添加元素 addLast()

泛型

  1. 用于约束外部对象的使用场景,就是类型;用于约束内部对象的使用场景,就是泛型。

  2. 泛型基础语法

  3. 比较器其实也使用了泛型

    public int compare(Integer o1,Integer o2){
    // 如果第一个数比第二个数大,那么返回结果为正数,表示升序
    return o1-o2;
    // 如果第一个数比第二个数小,那么返回结果为负数,表示降序
    return o2-o1;
    //如果第一个数与第二个数一样大,那么返回零,
    return 0;
    }

HashSet

  1. 增加数据 add(value)
  2. 删除数据 remove(value)
  3. 查询数据 set只能遍历查询
  4. 转换为数组 toArray()
  5. 清空元素 clear()
  6. HashSet判断元素不同的标准:HashCode不同,所以即使对象的属性相同,Hashcode不同,HashSet会认为其是两个元素。
  7. HashSet底层数据是数组+链表,

Queue

  1. ArrayBlockingQueue 数组+阻塞队列
  2. 添加元素 add() 当超过容量之后,会直接报错
  3. 添加元素 put() 超过容量之后,会直接堵塞,程序不会继续运行
  4. 添加元素 offer()
  5. 抛出元素 poll()

HashMap

  1. 添加数据 put(k,v)
  2. 查询数据 get(k)
  3. 删除数据 remove(k)
  4. 不覆盖添加数据 putIfAbsent(k,v)
  5. 修改数据 replace(k,v)
  6. 获取所有key值 keySet()
  7. 获得所有的value值 values()

HashTable

  1. TableMap的实现方式不一样;继承的父类不一样,而且Map(k,v)都可以为空
  2. Map的数据定位是哈希算法,Table采用的就是HashCode

迭代器

  1. 遍历hashmap时,可以使用迭代器进行遍历,并且进行删除修改操作

问题总结

  1. print数组的时候,直接输出数组得到的是内存地址,可以将其转换为字符串再进行print

IO

File file = new File(path);
//判断是否是文件
file.isFile();
//创建多级文件目录
file.mkdirs();
//创建新的文件夹
file.createNewFile();
  1. java中对于文件可以自动生成
  2. 缓冲流、字符流、序列化

线程

  1. 编译过程 javac 指令,生成字节码class

  2. Java 程序在运行的时候默认产生一个进程,这个进程会有一个主线程,代码都在主线程中执行

  3. 创建线程

    //TODO 创建线程
    MyTread t = new MyTread();

    //TODO 启动线程
    t.start();
  4. 并发:多线程之间彼此独立,互不影响

  5. 串行:多个线程连接成线,顺序执行

    Tread t1 = new Tread();
    Tread t2 = new Tread();
    //并发
    t1.start();
    t2.start();
    //串行
    t1.join();
    t2.join();
  6. 休眠

    Thread.slppe(1000);
  7. 快速传递逻辑

    Thread T = new Thread(() -> {
    System.out.println("逻辑传递");
    });
    T.start();
  8. 线程池,就是线程对象的容器,根据需求在启动时可以创建一个或者多个线程对象,Java中常见的线程池包括4种

    //TODO 固定数量线程池
    //executorService是线程服务对象
    ExecutorService executorService = Executors.newFixedThreadPool(3);

    //根据需求动态创建线程
    ExecutorService executorService = Executors.newCachedThreadPool();

    //单一线程,隐含线程顺序
    ExecutorService executorService = Executors.newSingleThreadExecutor();

    //定时调度线程,可以自定义调度时间
    ExecutorService executorService = Executors.newScheduledThreadPool(3)
    1. synchronized 同步关键字,多个线程访问同步方法的时候,只能一个一个访问,同步操作;修饰代码块,使得代码块成为同步代码块。
    2. synchronized具有原子性、可见性和有序性
    3. img
    4. 同步理解如下,对于一个对象x=0,线程A第一次访问时,由于本地内存中没有x,需要将其从主内存缓存到本地内存A中,进行更改x=1,并将其放回到主内存中;线程B第一次访问则将x=1读入本地内容B中,并修改为x=2然后放回主内存中。线程A第二次访问x时,由于本地内存A中存在,则会直接是使用本地内存中x=1,因此会出现内存不可见的问题。
    5. wait() 需要等待其他进程释放资源之后,线程才能够继续进行,属于被迫性的阻塞
    6. sleep() 线程自动的休眠,主动性的阻塞
    7. wait() Object类中的成员方法,因此每一个对象都会有wait方法;必须在同步代码块中才能使用;如果执行wait()方法,其他线程可以执行当前的同步操作
    8. sleep() Thread类中的静态方法,在任意情况下都可以使用,其他线程不能执行当前的同步操作。
    9. java对每一个线程创建一个栈内存,但是对于每一个对象,在堆中开辟新的空间。因此,在多个线程并发执行的时候,修改共享内存中对象的属性,会导致数据冲突问题。

反射

  1. Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性

结语

​ 由于时间仓促,短暂学习后在读博和工作之间举棋不定,后经深思熟虑,决定专攻学术研究,因此Java语法暂时告一段落。因此本篇难免显得虎头蛇尾,若有机会,小子定会补全(抱拳)