java入门

快速入门

JDK,JVM,JRE的关系

jdk是Java开发工具包,其中包括编译工具(javac.exe)打包工具(jar.exe)等,也包括JRE

关系:jdk包含了jre,而jre又包含了jvm

总结:jdk用于java程序的开发,jre只能运行class文件,而没有编译功能

联系:JVM不能单独对class文件的执行,解释class的时候JVM需要调用JRE 的类库lib。在JRE目录里有两个文件夹bin和lib,可以认为bin里的就是 jvm,lib里的则是jvm工作所需要的类库,而jvm和 lib和起来就称为JRE。

数据类型

  • 基本数据类型

    • 整数类型:byte,short (2字节),int (4字节),long (8字节)
    • 浮点数类型:float (4字节),double(8字节)
    • 字符类型:char (2字节)
    • 布尔类型:boolean
  • 整型

    只定义了带符号的整型

    • byte:-128 ~ 127
    • short: -32768 ~ 32767
    • int: -2147483648 ~ 2147483647
    • long: -9223372036854775808 ~ 9223372036854775807
  • 浮点型

    对于float类型,需要加上f后缀

    float类型可最大表示3.4x1038,而double类型可最大表示1.79x10308。

  • 引用类型

    • String 内部存储一个"地址",指向某个对象在内存的位置
  • 常量

    定义常量时,加上final修饰, 常量的变量名使用大写字母

  • var关键字

    有些时候,类型的名字太长,写起来比较麻烦。例如:

    StringBuilder sb = new StringBuilder();
    

    这个时候,如果想省略变量类型,可以使用var关键字:

    var sb = new StringBuilder();
    

定义变量时,要遵循作用域最小化原则,尽量将变量定义在尽可能小的作用域,并且,不要重复使用变量名

字符和字符串

  • 字符类型

    字符类型char是基本数据类型,它是character的缩写。一个char保存一个Unicode字符

    char c1 = 'A';
    char c2 = '中';
    
  • 字符串类型

    和char类型不同,字符串类型String是引用类型,我们用双引号"…………" 表示字符串。一个字符串可以存储0到任意个字符

  • 字符串类型的不可变性

    String 类使用fianl修饰不可被继承,不能被修改

数组类型

  • 定义数据的方式 (数组属于引用类型,数组长度不可变)

    // 数组
    public class Main {
        public static void main(String[] args) {
            // 5位同学的成绩:
            int[] ns = new int[5];
            System.out.println(ns.length); // 5
            
             // 5位同学的成绩:
            int[] ns = new int[] { 68, 79, 91, 85, 62 };
            int[] ns = { 68, 79, 91, 85, 62 };
            System.out.println(ns.length); // 编译器自动推算数组大小为5
            
        }
    }
    

流程控制

if条件判断

if (条件) {
    // 条件满足时执行
}

if - else

// 条件判断
public class Main {
    public static void main(String[] args) {
        int n = 70;
        if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("挂科了");
        }
        System.out.println("END");
    }
}

if - else if - else

// 条件判断
public class Main {
    public static void main(String[] args) {
        int n = 70;
        if (n >= 90) {
            System.out.println("优秀");
        } else if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("挂科了");
        }
        System.out.println("END");
    }
}

判断引用类型相等

  • 判断值类型相等使用==
  • 判断引用类是否相等,==表示"引用是否相等",或者说,是否指向同一个对象
  • 需要判断引用类型的变量内容是否相等,必须使用equals()方法
// 条件判断
public class Main {
    public static void main(String[] args) {
        int n = 70;
        if (n >= 90) {
            System.out.println("优秀");
        } else if (n >= 60) {
            System.out.println("及格了");
        } else {
            System.out.println("挂科了");
        }
        System.out.println("END");
    }
}

switch

// switch
public class Main {
    public static void main(String[] args) {
        int option = 99;
        switch (option) {
        case 1:
            System.out.println("Selected 1");
            break;
        case 2:
            System.out.println("Selected 2");
            break;
        case 3:
            System.out.println("Selected 3");
            break;
        default:
            System.out.println("Selected other");
            break;
        }
    }
}

while

// while
public class Main {
    public static void main(String[] args) {
        int sum = 0; // 累加的和,初始化为0
        int n = 1;
        while (n <= 100) { // 循环条件是n <= 100
            sum = sum + n; // 把n累加到sum中
            n ++; // n自身加1
        }
        System.out.println(sum); // 5050
    }
}

do while

// do-while
public class Main {
    public static void main(String[] args) {
        int sum = 0;
        int n = 1;
        do {
            sum = sum + n;
            n ++;
        } while (n <= 100);
        System.out.println(sum);
    }
}

for 循环

// for
public class Main {
    public static void main(String[] args) {
        int sum = 0;
        for (int i=1; i<=100; i++) {
            sum = sum + i;
        }
        System.out.println(sum);
    }
}

break 和 continue

  • break 跳出当前循环
  • continue 结束当初循环

面向对象

  • 封装

    private方法 不允许外部调用

    // private method
    public class Main {
        public static void main(String[] args) {
            Person ming = new Person();
            ming.setBirth(2008);
            System.out.println(ming.getAge());
        }
    }
    
    class Person {
        private String name;
        private int birth;
    
        public void setBirth(int birth) {
            this.birth = birth;
        }
    
        public int getAge() {
            return calcAge(2019); // 调用private方法
        }
    
        // private方法:
        private int calcAge(int currentYear) {
            return currentYear - this.birth;
        }
    }
    
    • this关键字:始终指向当前实例,因此通过this.birth就可以访问到当前实例的字段,如果没有命名冲突,可以省略this

    • 构造方法

      每个类有默认的空参构造方法

      class Person {
          public Person() {
          }
      }
      

      如果显示定义了有参构造,那么空参构造也必须显示定义

    • 方法重载 : 方法名相同,参数列表不同,返回值类型通常都是相同的

  • 继承 extends

    子类自动获得了父类的所有非私有字段和属性,严禁定义与父类重名的字段

    • java只允许一个class继承自一个类,因此,一个类有且仅有一个父类,只有Object类特色,它没有父类

    • protected关键字可以把字段和方法的访问权限控制在继承树内部,一个protected字段和方法可以被其子类,以及子类的子类访问

    • super关键字表示父类(超类),子类引用父类的字段时,可以用super.fieldName

      class Student extends Person {
          public String hello() {
              return "Hello, " + super.name;
          }
      }
      
    • 任何class的构造方法,第一行语句必须是调用父类的构造方法,如果没有明确的调用父类方法,编译器会帮我们自动加一句super();

      class Student extends Person {
          protected int score;
      
          public Student(String name, int age, int score) {
              super(); // 自动调用父类的构造方法
              this.score = score;
          }
      }
      
    • 子类不会继承父类的构造方法

      • 阻止继承

        • 正常情况下,只要某个class 没有被final修饰,那么任何类都可以从该class继承

        • 从java15开始,运行使用sealed修饰class,并通过permits明确写出能够从该class集成的子类名称

          例如,定义一个Shape类:

          public sealed class Shape permits Rect, Circle, Triangle {
              ...
          }
          

          上述Shape类就是一个sealed类,它只允许指定的3个类继承它。如果写:

          public final class Rect extends Shape {...}
          

          是没问题的,因为Rect出现在Shapepermits列表中。但是,如果定义一个Ellipse就会报错:

          public final class Ellipse extends Shape {...}
          // Compile error: class is not allowed to extend sealed class: Shape
          

          原因是Ellipse并未出现在Shapepermits列表中。这种sealed类主要用于一些框架,防止继承被滥用。

          sealed类在Java 15中目前是预览状态,要启用它,必须使用参数--enable-preview--source 15

        • 向上转型 把一个子类类型安全地变为父类类型的赋值,被成为向上转型

          向上转型实际上是把一个子类型安全地变为更加抽象的父类型

          Student s = new Student();
          Person p = s; // upcasting, ok
          Object o1 = p; // upcasting, ok
          Object o2 = s; // upcasting, ok
          
        • 向下转型 把一个父类类型强制转型为子类类型

          • instanceof : 判断示例是否是某种类型,避免向下转型失败

            实际上判断一个变量所指向的实例是否是指定类型,或者这个类型的子类。如果一个引用变量为null,那么对任何instanceof的判断都为false

            Person p = new Person();
            System.out.println(p instanceof Person); // true
            System.out.println(p instanceof Student); // false
            
            Student s = new Student();
            System.out.println(s instanceof Person); // true
            System.out.println(s instanceof Student); // true
            
            Student n = null;
            System.out.println(n instanceof Student); // false
            
            Person p = new Student();
            if (p instanceof Student) {
                // 只有判断成功才会向下转型:
                Student s = (Student) p; // 一定会成功
            }
            
            
          • 子类和父类的关系是is,has关系不能用继承

  • 多态

    多态是指:针对某个类型的方法调用,其真正执行的方法取决于运行期间实际类型的方法

    • 方法重写: 父类与子类方法名相同,返回值相同,

重写Object方法 : 因为所有的class最终都继承自object,而object定义了几个重要的方法:

  • toString():把instance输出为String
  • equals():判断两个instance是否逻辑相等;
  • hashCode():计算一个instance的哈希值。
class Person {
    ...
    // 显示更有意义的字符串:
    @Override
    public String toString() {
        return "Person:name=" + name;
    }

    // 比较是否相等:
    @Override
    public boolean equals(Object o) {
        // 当且仅当o为Person类型:
        if (o instanceof Person) {
            Person p = (Person) o;
            // 并且name字段相同时,返回true:
            return this.name.equals(p.name);
        }
        return false;
    }

    // 计算hash:
    @Override
    public int hashCode() {
        return this.name.hashCode();
    }
}

调用super

在子类的重写方法中,如果要调用父类的被重写方法,可以通过super来调用

class Person {
    protected String name;
    public String hello() {
        return "Hello, " + name;
    }
}

class Student extends Person {
    @Override
    public String hello() {
        // 调用父类的hello()方法:
        return super.hello() + "!";
    }
}

final 如果一个父类不允许子类对它的某个方法进行重写,那么可以使用final标记

抽象类 abstract

无法实例化的抽象类有什么用?

因为抽象类本身设计成只能被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译会报错。因此抽象方法实际上相当于定义了"规范"。

接口 interface

在抽象类中,抽象方法本质上是定义接口规范:即规定高层类的接口,从而保证所有子类都有相同的接口实现,这样多态就能发挥出威力,如果一个抽象类没有字段,所有方法全部都是抽象方法:就可以把该抽象类改写为接口:interface

接口中连字段都不能有

接口可以实现多个interface

接口与抽象类对比

abstract class interface
继承 只能extends一个class 可以implements多个interface
字段 可以定义实例字段 不能定义实例字段
抽象方法 可以定义抽象方法 可以定义抽象方法
非抽象方法 可以定义非抽象方法 可以定义default方法
posted @ 2025-05-06 22:18  小郑[努力版]  阅读(48)  评论(0)    收藏  举报