Java基础知识

一、标识符规范

标识符必须以字母(汉字)、下划线、美元符号开头,其他部分可以是字母、下划线、美元符号,数字的任意组合。谨记不能以数字开头。java使用unicode字符集,汉字也可以用该字符集表示。因此汉字也可以用作变量名。
关键字不能用作标识符。
类名首字母需大写(Welcome)、方法和变量名遵循驼峰原则 snRsfService()

二、数据类型

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

1. 基本数据类型

Java基础知识_第1张图片

1.1数值型

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

Java基础知识_第2张图片

Java基础知识_第3张图片

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表示的

Java基础知识_第4张图片

1.3 布尔型

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

2. 引用数据类型

类(Class):自定义的类。类是对象的模板,它定义了对象的属性和方法。
接口(Interface):一种完全抽象的类,它只包含常量和方法的声明,没有实现。接口可以被类实现,以实现特定的行为。
数组(Array):一种数据结构,用于存储固定大小的同类型元素集合。
字符串(String):一种特殊的对象,用于表示文本数据。Java中的字符串是不可变的,一旦创建就不能修改其内容。
包装类(Wrapper Classes):基本数据类型的封装类,如Integer、Double、Character等。它们提供了基本数据类型到对象类型的桥梁,并提供了额外的功能。
其他自定义对象:除了上述提到的类型外,还包括用户自定义的类、枚举(Enum)、注解(Annotation)等。

三、关键字

1. static

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

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

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

2. final

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

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

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

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

3. this

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

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;
    }
}

 4. super

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

5. String StringBuilder StringBuffer

Java基础知识_第5张图片

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. 方法重载的条件

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

2. 对象实例化的方式

2.1 new

2.2 clone()

2.3 通过反射机制创建

//用 Class.forName方法获取类,在调用类的newinstance()方法
Class cls = Class.forName("com.dao.User");
User u = (User)cls.newInstance();

2.4 序列化反序列化

//将一个对象实例化后,进行序列化,再反序列化,也可以获得一个对象(远程通信的场景下使用)
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();

 3. 对象复制的方式

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

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

 4. 深拷贝与浅拷贝的区别

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

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

五、面向对象特性

1. 封装

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

Java基础知识_第6张图片

2. 继承

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

//instanceof 判断对象是否是某个类的实例对象
Stu stu = new Stu();
System.out.print(stu instanceof Stu);

3. 多态

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

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

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

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修饰的类是抽象类,包含抽象方法的类是抽象类。 

//模板方法模式(抽象类的应用)
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基础知识_第7张图片

//非静态内部类初始化
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基础知识_第8张图片

包装类与基本数据类型的转换过程就是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基础知识_第9张图片

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 的资源对象, 都可以用它进行关闭。

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();
        }
    }
}

十一、泛型

(待施工)

你可能感兴趣的:(java,基础知识,面试,初学者)