JAVA入门学习笔记#01(基础概念、基本语法和关键字)

本文假设读者已有其他面向对象高级语言的基础(如C++基础),在此基础上介绍 Java 的基础知识。

目录

1 基本名词解释

2 关键字

Java 中的访问控制符

Java 中的包

类与继承

其他变量修饰符

程序控制

错误处理

基本类型

变量引用

保留字


参考链接  JavaGuide(Java学习&面试指南)

1 基本名词解释

JAVA :一种面向对象的高级语言

JDK:Java Development Kit,功能齐全的 Java SDK,能够创建和编译 Java 程序的开发套件;Java 8 对应的 JDK 版本是 1.8

JRE:Java Runtime Environment, Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,主要包括 Java 虚拟机(JVM)、Java 基础类库(Class Library)

JVM:Java 虚拟机(Java Virtual Machine, JVM)是运行 Java 字节码的虚拟机。JVM 有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在

jar:Java Archive Tool,一种软件包文件格式,通常用于聚合大量的Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便开发Java平台应用软件或库

2 关键字

JAVA中的关键字如下

分类关键字
访问控制privateprotectedpublic

类,方法

和变量修

饰符

abstractclassextendsfinalimplementsinterfacenativeenum
newstaticstrictfpsynchronizedtransientvolatile
程序控制breakcontinuereturndowhileifelseassert
forinstanceofswitchcasedefault
错误处理trycatchthrowthrowsfinally
包相关importpackage
基本类型booleanbytechardoublefloatintlongshort
变量引用superthisvoid
保留字gotoconst

接下来分别介绍上述关键字

Java 中的访问控制符

  1. public:成员可以在任何地方被访问,包括同一包(Package)、不同包中的子类和其他类。

  2. protected

    • 成员可以在同一包内被访问,也可以被不同包中的子类访问。
    • protected成员对所有子类都可见,不论子类是否在同一包中。
  3. default(无访问修饰符)

    • 成员仅在同一包内可见。这有时被称为包访问权限。
  4. private

    • 成员仅在声明它的类内部可见。这是最严格的访问级别。

在Java中,继承总是 public 继承,所以 protected 成员总是对子类可见,而 private 成员则始终不可见。

Java 中的包

在Java中,(Package)是一种组织类和接口的方式,它可以帮助开发者管理类名空间,避免命名冲突,并控制类的可见性。

什么是包?

  • 是一组相关的类和接口的集合。
  • 包通过使用 package 关键字来声明。
  • 包名通常采用反向域名的形式,例如 com.example.myapp
  • 包可以嵌套在其他包中形成层次结构。

同一个包内

  • 同一个包内指的是那些具有相同包声明的类或接口。这意味着它们位于文件系统的同一目录下,并且它们的源文件都包含相同的package语句。
  • 在同一个包内的类可以互相访问默认访问级别的成员(即没有明确指定publicprotectedprivate的成员)。

包的作用

  • 避免命名冲突:通过使用不同的包名,可以确保不同项目中的类名即使相同也不会发生冲突。
  • 访问控制:包提供了一种方式来控制类和成员的可见性。例如,protected和默认访问级别的成员只能在同一个包内的类中访问。
  • 导入类:使用import语句可以方便地引用其他包中的类。

如何声明包

在Java源文件的顶部,你可以使用package关键字来声明一个包:

package com.example.myapp;

public class MyClass {
    // 类的定义
}

文件结构

假设你的文件系统结构如下:

src/
|-- com/
|   |-- example/
|       |-- myapp/
|           |-- PackageExample.java
|           |-- AnotherClass.java

PackageExample.java

package com.example.myapp;

public class PackageExample {
    // 默认访问级别的变量
    String message = "Hello from PackageExample!";

    public void displayMessage() {
        System.out.println(message);
    }
}

AnotherClass.java

package com.example.myapp;

public class AnotherClass {
    public static void main(String[] args) {
        PackageExample example = new PackageExample();
        System.out.println(example.message); // 访问同一个包内的默认访问级别的成员
        example.displayMessage();
    }
}

在这个示例中,PackageExampleAnotherClass都在com.example.myapp包内。因此,AnotherClass可以访问PackageExample中的默认访问级别的成员message

要编译和运行这些类,你需要确保它们位于正确的目录结构中,以匹配包声明。例如,如果你使用的是命令行编译器,你可以这样编译和运行:

# 编译
javac -d build src/com/example/myapp/PackageExample.java
javac -d build src/com/example/myapp/AnotherClass.java

# 运行
java -cp build com.example.myapp.AnotherClass

这里,-d build 指定了编译后的.class文件的输出目录,-cp build 设置了类路径。

编译运行后控制台会输出如下结果

Hello from PackageExample!
Hello from PackageExample!

import 关键字用于导入包的内容,有几种常用的导入方法:

  • 导入单个类:import java.util.Date;    // 关键字后跟完整的类名(包括包名)
  • 导入整个包:import java.util.*;    // 包后面用*
  • 导入静态成员:import static java.lang.Math.PI;    // 加上 static 关键字

类与继承

  • static:声明静态成员(包括类内的变量和函数),静态成员在类加载得到时候就已经被分配内存已经存在了(而不是等到实例化的时候才有),且只在类初始化时分配一次内存(而不是每个类分配一次),所有类的实例都可以访问静态成员,静态成员可以直接通过类名调用(无需实例化)
  • new:实例化一个新对象,在 Java 中使用 new 来声明一个新对象会自动调用构造函数(并在使用完后自动调用析构函数)
  • abstract:用于声明抽象类或抽象方法,抽象类或抽象方法需在子类中强制重写
  • class:声明一个类
  • extends:MyClassA extends MyClassB 表示 MyClassA 继承类 MyClassB ,注意 Java 中只允许单继承,不允许多继承
  • implements:implements 是用于实现接口的关键字。当一个类需要实现一个或多个接口时,会使用 implements 关键字。接口只包含方法签名(没有方法体),并且可以包含常量。实现接口的类必须提供接口中所有方法的具体实现,除非该类本身是抽象类。例如:
interface CanEat {
    void eat();
}

class Animal {}

class Dog extends Animal implements CanEat {
    @Override
    public void eat() {
        System.out.println("The dog is eating.");
    }
}

        上述例子中,Dog类继承了Animal类并实现了CanEat接口,因此它必须提供eat()方法的实现。

总结来说,extends用于继承类,支持单继承(一个类只能有一个直接父类),而implements用于实现接口,支持多重实现(一个类可以实现多个接口)。

这两种机制都允许代码复用,但以不同的方式实现。类继承更多地用于结构和行为的复用,而接口实现则用于定义行为的规范。

  • interface:要使用 implements 关键字继承的抽象父类,示例代码见下 default。
  • default:从 Java8 开始,在使用 interface 声明的抽象父类中,可以有函数有默认的实现方法(在子类的接口中可以不用重写 dafault 方法,要重写的话要加上 @Override),例如:

现有提供的 Drawable 接口中定义了一个 showInfo() 方法:

public interface Drawable {
    void draw(); // 抽象方法
    default void showInfo() {
        System.out.println("This is a drawable object.");
    }
}

这里 showInfo() 方法是默认方法,它有一个具体的实现。任何实现了 Drawable 接口的类都会自动获得这个方法的new实现,除非该类明确地覆盖(@Override)了这个方法。

public class Circle implements Drawable {
    @Override
    public void draw() {
        System.out.println("Drawing a circle.");
    }
}

public class Square implements Drawable {
// 如果 Square 类要继承自多个父类,则用 “,” 分开
// 如 public class Square implements Drawable, Resize {
    @Override
    public void draw() {
        System.out.println("Drawing a square.");
    }
    
    // 如果需要覆盖默认方法,可以这样做:
    @Override
    public void showInfo() {
        System.out.println("This is a square.");
    }
}

在这个例子中,Circle 类没有覆盖 showInfo() 方法,因此它会使用 Drawable 接口中定义的默认实现。而 Square 类覆盖了 showInfo() 方法,提供了自己的实现。

default 关键字提供向后兼容性,允许在现有接口中添加新方法而不破坏现有的实现。

  • final:用 final 关键字修饰的类、方法和变量不可再继承、重写和修改;但如果final变量引用的是一个对象,那么final关键字保证的是引用不会改变,而不是对象的内容。也就是说,你不能改变final变量指向的引用,但如果你的final变量引用的是一个可变对象(如ArrayList),你仍然可以改变对象内部的状态。例如:
final List<String> list = new ArrayList<>();
list.add("Item"); // 这是允许的

其他变量修饰符

  • native:native关键字用于声明一个方法是由本地其他代码(如C或C++)实现的,而不是由Java代码实现的。native关键字通常与publicprotectedprivate等访问修饰符一起使用,但不能与finalabstractsynchronizedstrictfp等关键字一起使用,因为它们与本地方法的概念不兼容。
  • strictfp:该关键字用于确保浮点数运算的精度和一致性。它主要用于限制浮点数运算的执行模式,以确保跨平台的结果一致性。
  • synchronized:该关键字通过锁机制实现线程同步,以确保多个线程之间的互斥访问,防止数据竞争条件的发生。synchronized可以用于方法或者代码块,确保同一时刻只有一个线程能够执行被同步的代码。
  • transient:用于标记类中的成员变量,表明该变量不应该被序列化。序列化是将对象的状态转换为字节流的过程,以便可以存储或在网络上传输。
  • volatile:修饰的变量每次读都会从主内存(Main Memory)中加载该变量的最新值,而不是从线程的工作内存(Working Memory)中读取可能已过期的副本。这样当主线程改变volatile修饰的变量值时,正在运行的任务线程会立即看到这个变化。但 volatile 并不保证操作的原子性,复杂的操作可能还是需要 synchronized 进行。
  • enum:enum即枚举是一种特殊的类,用于定义一组固定的常量,通常代表有限集合中的元素。枚举提供了一种类型安全的方式来表示一组相关的常量,而不是使用整数或字符串。更详细的示例可见Java 枚举(超详细讲解)

程序控制

break, continue, return, do, while, if, else, for, switch, case, default 都和 C++ 中的类似

  • instanceof:判断某个实例是否是某个类或其子类,示例如下
要检查的实例 instanceof 类名
  • assert:断言,假设此处应该满足某种条件,不然会抛出什么错误,示例如下
assert <布尔表达式> : <可选的错误信息>;

错误处理

用下列代码说明 Java 中的 try, catch, throw, throws 和finally 关键字

public class ExceptionDemo {

    public static void main(String[] args) {
        try {
            // 尝试执行可能会抛出异常的代码
            performAction();
        } catch (ArithmeticException e) {
            // 处理特定类型的异常
            System.out.println("Caught an ArithmeticException: " + e.getMessage());
        } catch (Exception e) {
            // 处理其他类型的异常
            System.out.println("Caught another exception: " + e.getMessage());
        } finally {
            // 总是执行的代码,无论是否有异常发生
            System.out.println("Finally block executed.");
        }
    }

    public static void performAction() throws IOException {
        try {
            // 抛出一个异常
            throw new ArithmeticException("Divide by zero error.");
        } catch (ArithmeticException e) {
            // 在方法内部处理异常,然后再次抛出
            System.out.println("Handling ArithmeticException in performAction()");
            throw e;
        } finally {
            // 清理资源或执行必要的关闭操作
            System.out.println("Cleaning up resources in performAction().");
        }
    }
}

其中 throws 关键字表明 performAction() 方法可能会抛出 IOException 异常。当你在方法签名中使用 throws 关键字时,你告诉调用者(或其他方法)这个方法在执行过程中可能会抛出特定类型的异常,调用者应该准备好处理这些异常,要么通过自己的 try-catch 块捕获它们,要么继续在调用链中声明这些异常。

throws 关键字后跟一个或多个异常类的名称,这些异常类应该是具体的异常类型,通常是 Exception 类或其子类。

基本类型

Java中的基本数据类型(Primitive Data Types)是直接存储值的类型,它们不是对象,也不需要在堆上分配内存。Java提供了八种基本数据类型,分为四类:

  1. 整型 (Integer Types)

    • byte: 占用1个字节(8位),范围从-128到127。
    • short: 占用2个字节(16位),范围从-32,768到32,767。
    • int: 占用4个字节(32位),范围从-2,147,483,648到2,147,483,647。
    • long: 占用8个字节(64位),范围从-9,223,372,036,854,775,808到9,223,372,036,854,775,807。
  2. 浮点型 (Floating Point Types)

    • float: 占用4个字节(32位),可以表示小数,有效数字约为7位。
    • double: 占用8个字节(64位),可以表示小数,有效数字约为15位,精度高于float
  3. 字符型 (Character Type)

    • char: 占用2个字节(16位),用于存储Unicode字符。
  4. 布尔型 (Boolean Type)

    • boolean: 只有两个值,truefalse,不占用固定的字节数,但通常被实现为占1个字节。

Java 中每种基本类型都有对应的包装类,如Integer对应intDouble对应double等,这使得基本类型可以作为对象使用,从而支持一些面向对象的特性,如方法调用和异常处理。

变量引用

  • super:

    在Java中,super 关键字用于引用当前对象的直接父类的对象。它可以在子类中调用父类的构造函数、父类普通函数,访问父类的字段或其成员变量,示例代码如下:
     

       public class Child extends Parent {
           public Child() {
               super(); // 调用Parent类的无参构造器
           }
    
           public void someMethod() {
               super.someMethod(); // 子类重写父类的方法,仍可调用父类被重写的方法
               // 其他代码...
           }
       // 如果子类和父类中有同名的字段,可用super.field来访问父类中的字段
    
           private int field; // 子类也有一个field字段
    
           public void printField() {
               System.out.println(super.field); // 访问Parent类的field字段
           }
    
       // 在子类的构造函数中初始化父类的成员变量,这时可以使用super
           private String childProperty;
    
           public Child(String parentProperty, String childProperty) {
               super(parentProperty); // 初始化Parent类的成员变量
               this.childProperty = childProperty;
           }
       }

    super  关键字不能在静态方法或静态字段中使用,因为静态成员与类相关联,而不是与类的实例相关联。因此,它们不能访问非静态的父类成员。

  • this:指向本类

  • void:表示本函数不返回任何东西

保留字

  • goto:Java 中避免使用 goto,可以使用 break 和 continue 来跳出多重循环
  • const:Java 中避免使用 const,可以使用 final 来实现常量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值