Java基础知识

一、标识符规范

标识符必须以字母(汉字)、下划线、美元符号开头,其他部分可以是字母、下划线、美元符号,数字的任意组合。谨记不能以数字开头。java使用unicode字符集,汉字也可以用该字符集表示。因此汉字也可以用作变量名。

关键字不能用作标识符。

类名首字母需大写(Welcome)、方法和变量名遵循驼峰原则 snRsfService()

二、数据类型

java的数据类型由8种基本数据类型和多种引用数据类型构成。

  1. 基本数据类型

1.1数值型

数值型又分为整数类型和浮点类型。

java 复制代码
long l = 10000000000L;   //整型数据默认是int, 转成long后面要加 L 或 l
float f = 3.14F;   //浮点常量默认是double,改成float后面要加F 或 f

<一些可有可无的科普:计算机底层浮点数表示方法>
在计算机底层float和double都是由IEEE754标准进行储存的,该标准将浮点数分成符号位、指数位、尾数位。分配如下:
单精度浮点数float:32bit(4字节)
1bit(符号位)
8bits(指数位)
23bits(尾数位)

双精度浮点数double:64bit(8字节)
1bit(符号位)
11bits(指数位)
52bits(尾数位)
数据的表示范围是由指数的位数来决定的。float的指数位有8位,能表示0-255一共256个状态。加之IEEE标准规定有127的偏移量,float的指数最大值为128。float的范围为-2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38;double范围的计算方法和float同理。double的范围为-2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308。
精确度是由尾数的位数来决定的。float的尾数位有23位,能表示最大7位十进制数字,但实际精度取决于浮点数的具体值。double的尾数位有52位,能表示最大16位十进制数字,但实际精度同样取决于浮点数的具体值。
(尽量不要在比较和金额计算中使用浮点数,精确计算用BigDecimal)

1.2 字符型

内存中占2个字节,unicode就是用char表示的

1.3 布尔型

在内存中占1 或4个字节(JVM用int表示bool,CPU层面有利于高效存取)

  1. 引用数据类型

类(Class):自定义的类。类是对象的模板,它定义了对象的属性和方法。

接口(Interface):一种完全抽象的类,它只包含常量和方法的声明,没有实现。接口可以被类实现,以实现特定的行为。

数组(Array):一种数据结构,用于存储固定大小的同类型元素集合。

字符串(String):一种特殊的对象,用于表示文本数据。Java中的字符串是不可变的,一旦创建就不能修改其内容。

包装类(Wrapper Classes):基本数据类型的封装类,如Integer、Double、Character等。它们提供了基本数据类型到对象类型的桥梁,并提供了额外的功能。

其他自定义对象:除了上述提到的类型外,还包括用户自定义的类、枚举(Enum)、注解(Annotation)等。

三、关键字

  1. static

static修饰变量:静态变量又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量 ,可以直接通过类名来访问它。静态变量在内存中只存在一份

static修饰函数:静态方法在类加载的时候就存在 了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。

static修饰代码块:静态代码块在类构造函数之前被执行。

  1. final

final修饰变量:修饰基本数据类型时,表示这个变量值不可变。

final修饰引用数据类型:表示这个变量引用不可变,但引用的对象具体内容是可以改变的(比如对象的某个属性值是可变的)。

final修饰方法:表示此方法不可被子类重写。

final修饰类:表示此类不可以被继承。

  1. this

this的本质就是当前对象的地址。普通方法中,this指向调用该方法的对象。构造方法中,指向正要初始化的对象。

java 复制代码
class User{
    int id;
    String name;
    String pwd;
    User(){}
    public User(int id, String name){
        this.id = id;
        this.name = name;
    }
    public User(int id, String name, String pwd){
        this(id, name);//构造方法重载,该种调用必须位于构造方法的第一行
        this.pwd = pwd;
    }
}
  1. super

super可以看做父类对象的引用,但是创建子类对象的过程并没有产生父类对象,super代表当前对象的父类型特征。在一个类中,如果构造方法的第一行代码没有显式的使用super()或this(),那么java都会默认调用super()

  1. String StringBuilder StringBuffer

String表示字符串,从jdk1.0开始就出现了。从Java7版本开始存在于堆中的字符串常量池中。其底层使用一个数组进行存放,在JAVA8中是一个char数组,而在JAVA9中是一个byte数组,并且这个数组使用final进行修饰,表示不可变的。所以String类是天生线程安全的。

StringBuffer是为了解决String类在内容频繁变化时,性能不高这个问题。表示的是一个可变长度字符串,他也是在Jdk1.0中就出现了,其内部的方法都是被Synchronized修饰,所以他是线程安全的。并且在stringBuffer有个缓存数组一直缓存变化着的内容(缓存最后一个值)。它的toString方法的返回值就是这个缓存数组的String对象。这一点和stringBuilder不一样,stringbuilder的tostring返回值是通过存储他的那个数组创建的。

虽然说这一点不同StringBuilder也是表示可变长度字符串。他是从JDK1.5开始出现的,其方法没有被Synchronized修饰,是非线程安全的,但它的性能相对于StringBuilder更高。

四、方法与对象

  1. 方法重载的条件

形参类型,个数,顺序不同即可构成方法重载。只有返回值不同不构成方法重载,会报编译错误。

  1. 对象实例化的方式

2.1 new

2.2 clone()

2.3 通过反射机制创建

java 复制代码
//用 Class.forName方法获取类,在调用类的newinstance()方法
Class<?> cls = Class.forName("com.dao.User");
User u = (User)cls.newInstance();

2.4 序列化反序列化

java 复制代码
//将一个对象实例化后,进行序列化,再反序列化,也可以获得一个对象(远程通信的场景下使用)
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream("D:/data.txt"));
//序列化对象
out.writeObject(user1); 
out.close();
//反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("D:/data.txt"));
User user2 = (User) in.readObject();
System.out.println("反序列化user:" + user2);
in.close();
  1. 对象复制的方式

通过构造方法、通过对象的值、通过object的clone方法。

java 复制代码
//通过构造方法
TestClone tc = new TestClone();
tc.name = 123;
TestClone tc2 = new TestClone(tc);
//通过对象的值
直接将老对象的值挨个复制给新对象即可
//通过object的clone方法
通过该方式复制对象时必须重写cloneable的clone方法。
  1. 深拷贝与浅拷贝的区别

浅拷贝:仅仅克隆基本类型变量,不克隆引用类型变量;

深拷贝:既克隆基本类型变量,又克隆引用类型变量;

五、面向对象特性

  1. 封装

将对象的属性包裹起来,并通过接口控制访问。高内聚低耦合,并隐藏实现细节,安全性高。

  1. 继承

java类没有多继承,即子类只能继承一个父类,接口有多继承。子类继承父类可以得到除构造方法外的全部非私有属性和方法。java.lang.Object是所有类的父类。

java 复制代码
//instanceof 判断对象是否是某个类的实例对象
Stu stu = new Stu();
System.out.print(stu instanceof Stu);
  1. 多态

同一个方法调用,由于对象不同,可能有不同的行为。多态是方法的多态不是属性的多态。优点是简化灵活,替换性强,可拓展性高。

三个必要条件是重写,继承和父类引用指向子类对象。

当指向子类对象的父类引用,调用子类重写的父类方法时,多态就出现了。

java 复制代码
public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 对象调用 show 方法
      show(new Dog());  // 以 Dog 对象调用 show 方法
                
      Animal a = new Cat();  // 向上转型  
      a.eat();               // 调用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下转型  
      c.work();        // 调用的是 Cat 的 work
  }  
            
    public static void show(Animal a)  {
      a.eat();  
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}
 
abstract class Animal {  
    abstract void eat();  
}  
  
class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃鱼");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  
  
class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨头");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

六、抽象类

使用abstract修饰的类是抽象类,包含抽象方法的类是抽象类。

java 复制代码
//模板方法模式(抽象类的应用)
public abstract class DBOperator {
    //1. 建立连接  2. 打开数据库  3. 使用数据库  4. 关闭连接
    public abstract void connection();
    public void open(){
        System.out.println("打开数据库");
    }
    public void use(){
        System.out.println("使用数据库");
    }
    public void close(){
        System.out.println("关闭连接");
    }

    public void process(){
        connection();
        open();
        use();
        close();
    }

    public static void main(String[] args) {
//        new MySqlOperator().process();
        new OracleOperator().process();
    }

}

class MySqlOperator extends DBOperator {

    @Override
    public void connection() {
        System.out.println("建立和Mysql数据库的连接");
    }
}

class OracleOperator extends  DBOperator {
    @Override
    public void connection() {
        System.out.println("建立和Oracle数据库的连接");
    }
}

七、接口

由全局常量(public static final 可省略)、抽象方法(public abstract)、默认方法(public default)、静态方法(public static)组成,其中方法的public可省略。java9中接口可以包含只能被接口内部调用的私有方法。

常量:接口中可以定义常量,这些常量默认是public static final的,即它们是公共的、静态的、不可变的。接口不能包含变量。

抽象方法:接口中可以包含抽象方法,这些方法只有方法签名,没有方法体。抽象方法默认是public abstract的,即它们是公共的、抽象的。实现接口的类必须提供接口中所有抽象方法的具体实现。

默认方法:这些方法有方法体,因此可以提供默认实现。可以被重写。

静态方法:这些方法有方法体,可以直接通过接口名调用,而不需要实现类的实例。静态方法使用static关键字定义,实现类不能重写接口的静态方法。静态方法只能调用接口中的其他静态方法或私有静态方法。

命名冲突问题:

对于一个实现了多个接口且继承自某一个父类的子类,如果方法名和形参列表相同,会发生命名冲突。若父类的方法和接口默认方法名冲突,则父类优先。若多个接口默认方法导致命名冲突,则子类需重写该方法。

八、内部类

为了方便使用外部类相关的属性和方法,通常会在开发中定义一个内部类。

内部类可以直接访问外部类的私有属性,但外部类不能访问内部类的属性。内部类被当成外部类的成员。SubList就是ArrayList的内部类。

java 复制代码
//非静态内部类初始化
Outer.Inner inner = new Outer().new Inner();
//静态内部类初始化
Outer.Inner inner = new Outer.Inner();


//匿名内部类,适合只使用一次的类
/**
    目标:掌握匿名内部类的使用形式
 */
public class Test {
    public static void main(String[] args) {
    //使用匿名内部类替代学生类,创建的类型是new的那个类的子类
        Swimming s = new Swimming() {
            @Override
            public void Swim() {
                System.out.println("学生游的很快");
            }
        };
        go(s);
    }

    /**
        方法:学生、老师、运动员可以一起游泳
     */
    public static void go(Swimming s)
    {
        System.out.println("开始游泳了~~");
        s.Swim();
        System.out.println("结束游泳了~~");
    }
}
//创建学生类
/*class Student implements Swimming{
    @Override
    public void Swim() {
        System.out.println("学生游的很快");
    }
}*/

//定义一个接口规范游泳
interface Swimming{
    void Swim();
}

九、包装类

包装类与基本数据类型的转换过程就是java的自动装箱与拆箱,在性能敏感的应用中,过度使用会导致性能下降,因为需要额外的内存分配和垃圾回收。

java 复制代码
Integer ele = new Integer(10);
int ele3 = ele.intValue();

//自动装箱
Integer ele2 = 10;
//自动拆箱
int ele4= ele;

//Integer包装类缓存范围[-128,127]
Integer a = 100;
Integer b = 100;
System.out.println(a==b);//true
Integer a1 = 200;
Integer b1 = 200;
System.out.println(a1==b1);//false

<一些不必要的知识点:包装类默认缓存范围>
Boolean:true和false
Integer:-128~127
Byte:-128~127
Character:0~127
Short:-128~127
Long:-128~127
Float和Double无缓存

十、异常机制

java中的异常都继承自Throwable类,分为Error和Exception。Error表示编译或系统错误,如OOM和StackOverFlow。Exception表示程序可以捕获或处理的异常,又分为运行时异常和非运行时异常。

RuntimeException 是运行时异常,这类异常是不受检查的,需要程序员自己决定要不要做处理。RuntimeException 以外的异常都属于非运行时异常。例如 IOException、ClassCastException 等以及用户自定义的 Exception 异常等。

<一些不必要的知识点:try-cache-finally 与 try-with-resouce>

前者中的finally一定会被运行,但遇见如下情况不会执行:比如退出程序,finally 语句块中发生了异常,还有程序所在的线程死亡。try-with-resouce可以保证运行结束后每个资源都被自动关闭。任何实现了 java.lang.AutoCloseable 的对象, 包括所有实现了 java.io.Closeable 的资源对象, 都可以用它进行关闭。

java 复制代码
public class MyAutoClosable implements AutoCloseable {
    public void doIt() {
        System.out.println("MyAutoClosable doing it!");
    }
    @Override
    public void close() throws Exception {
        System.out.println("MyAutoClosable closed!");
    }
    public static void main(String[] args) {
        try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
            myAutoClosable.doIt();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

十一、泛型

(待施工)

相关推荐
云间月131410 分钟前
飞算JavaAI智慧文旅场景实践:从景区管理到游客服务的全链路系统搭建
java·开发语言
盖世英雄酱5813610 分钟前
必须掌握的【InheritableThreadLocal】
java·后端
绝无仅有14 分钟前
编写 Go 项目的 Dockerfile 文件及生成 Docker 镜像
后端·面试·github
找不到、了16 分钟前
JVM的逃逸分析深入学习
java·jvm
绝无仅有26 分钟前
使用 Docker 部署 Go 项目(Beego 框架)
后端·面试·github
用户03321266636730 分钟前
Java 查找并替换 PDF 中的文本:高效自动化处理指南
java
叽哥39 分钟前
Kotlin学习第 1 课:Kotlin 入门准备:搭建学习环境与认知基础
android·java·kotlin
Hy行者勇哥1 小时前
物联网软件开发过程中,数据流图(DFD),用例图,类图,活动图,序列图,状态图,实体关系图(ERD),BPMN(业务流程建模)详解分析
java·物联网·struts
luckyCover1 小时前
面试前来了解下TCP/IP网络模型吧~
前端·面试
Miracle6581 小时前
从 0 到 1 开发校园二手交易系统:飞算 JavaAI 全流程实战
java