Java从入门到入土

#1024程序员节 | 征文#

Java教程

Java 教程 | 菜鸟教程 (runoob.com)

(声明:本文来自菜鸟教程加个人理解,适用于有一定语言基础的小伙伴食用)

Java简介★

主要特性

  • Java 语言是简单的:

    Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。

  • Java 语言是面向对象的:

    Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。

  • Java语言是分布式的:

    Java 语言支持 Internet 应用的开发,在基本的 Java 应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括 URL、URLConnection、Socket、ServerSocket 等。Java 的 RMI(远程方法激活)机制也是开发分布式应用的重要手段。

  • Java 语言是健壮的:

    Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。

  • Java语言是安全的:

    Java通常被用在网络环境中,为此,Java 提供了一个安全机制以防恶意代码的攻击。除了Java 语言具有的许多安全特性以外,Java 对通过网络下载的类具有一个安全防范机制(类 ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类 SecurityManager)让 Java 应用设置安全哨兵。

  • Java 语言是体系结构中立的:

    Java 程序(后缀为 java 的文件)在 Java 平台上被编译为体系结构中立的字节码格式(后缀为 class 的文件),然后可以在实现这个 Java 平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。

  • Java 语言是可移植的:

    这种可移植性来源于体系结构中立性,另外,Java 还严格规定了各个基本数据类型的长度。Java 系统本身也具有很强的可移植性,Java 编译器是用 Java 实现的,Java 的运行环境是用 ANSI C 实现的。

  • Java 语言是解释型的:

    如前所述,Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。

  • Java 是高性能的:

    与那些解释型的高级脚本语言相比,Java 的确是高性能的。事实上,Java 的运行速度随着 JIT(Just-In-Time)编译器技术的发展越来越接近于 C++。

  • Java 语言是多线程的:

    在 Java 语言中,线程是一种特殊的对象,它必须由 Thread 类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为 Thread(Runnable) 的构造子类将一个实现了 Runnable 接口的对象包装成一个线程,其二,从 Thread 类派生出子类并重写 run 方法,使用该子类创建的对象即为线程。值得注意的是 Thread 类已经实现了 Runnable 接口,因此,任何一个线程均有它的 run 方法,而 run 方法中包含了线程所要运行的代码。线程的活动由一组方法来控制。Java 语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为 synchronized)。

  • Java 语言是动态的:

    Java 语言的设计目标之一是适应于动态变化的环境。Java 程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java 中的类有一个运行时刻的表示,能进行运行时刻的类型检查。

Java 开发环境配置

Java AI 编程助手

Java 基础语法

一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。

  • 对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
  • :类是一个模板,它描述一类对象的行为和状态。
  • 方法:方法就是行为,一个类可以有很多方法。逻辑运算、数据修改以及所有动作都是在方法中完成的。
  • 实例变量:每个对象都有独特的实例变量,对象的状态由这些实例变量的值决定。

82d9e91cef810bbcad2c3557b194f76f.jpeg

基本语法

编写 Java 程序时,应注意以下几点:

  • 类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass 。
  • 方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
  • 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。
  • 主方法入口:所有的 Java 程序由 public static void main(String[] args) 方法开始执行

java标识符

  • 合法标识符举例:age、$salary、_value、__1_value
  • 非法标识符举例:123abc、-salary

Java 关键字

下面列出了 Java 关键字。这些保留字不能用于常量、变量、和任何标识符的名称。

类别关键字说明
访问控制private私有的
protected受保护的
public公共的
default默认
类、方法和变量修饰符abstract声明抽象
class
extends扩充、继承
final最终值、不可改变的
implements实现(接口)
interface接口
native本地、原生方法(非 Java 实现)
new创建
static静态
strictfp严格浮点、精准浮点
synchronized线程、同步
transient短暂
volatile易失
程序控制语句break跳出循环
case定义一个值以供 switch 选择
continue继续
do运行
else否则
for循环
if如果
instanceof实例
return返回
switch根据值选择执行
while循环
错误处理assert断言表达式是否为真
catch捕捉异常
finally有没有异常都执行
throw抛出一个异常对象
throws声明一个异常可能被抛出
try捕获异常
包相关import引入
package
基本类型boolean布尔型
byte字节型
char字符型
double双精度浮点
float单精度浮点
int整型
long长整型
short短整型
变量引用super父类、超类
this本类
void无返回值
保留关键字goto是关键字,但不能使用
const是关键字,但不能使用

注意:Java 的 null 不是关键字,类似于 true 和 false,它是一个字面常量,不允许作为标识符使用。

Java 空行

空白行或者有注释的行,Java 编译器都会忽略掉。

Java 源程序与编译型运行区别

如下图所示:

59eb4a0f013d9eee2702c9ae247b06dc.png

“半编译半解释”语言

Java 既不是纯粹的解释型语言,也不是纯粹的编译型语言,而是两者结合的一种语言,通常被称为“半编译半解释”语言。这种特性是由 Java 的执行机制决定的:

编译过程

  • 当你编写完 Java 代码后,首先需要通过 Java 编译器(javac)将源代码(.java 文件)编译成字节码(.class 文件)。这个过程与传统编译型语言类似,生成的字节码是一种中间形式的代码,独立于具体的机器架构。

解释过程

  • 字节码文件随后会被加载到 Java 虚拟机(JVM)中运行。JVM 是一个虚拟的计算机,它负责解释并执行字节码。JVM 会根据运行时的具体环境(如操作系统和硬件),将字节码转换成对应的机器码来执行。

即时编译(Just-In-Time Compilation, JIT)

  • 为了提高性能,现代的 JVM 实现了即时编译技术。JIT 编译器会在运行时分析程序的执行情况,将频繁执行的字节码部分直接编译成机器码,从而避免每次执行时都需要进行解释。这样可以显著提高程序的执行效率。

总结来说,Java 代码首先被编译成字节码,然后在 JVM 中通过解释或即时编译的方式执行。这种方式结合了编译型语言的性能优势和解释型语言的灵活性,使得 Java 具有“一次编写,到处运行”的特点。

Java注释

单行注释:

和C语言一样,单行注释以双斜杠 // 开始:

多行注释:

和C语言一样,多行注释以 /*开始,以 */结束:

文档注释:

文档注释的格式通常包含一些特定的标签,如 @param 用于描述方法参数,@return 用于描述返回值,@throws 用于描述可能抛出的异常等等,这些标签有助于生成清晰的API文档,以便其他开发者能够更好地理解和使用你的代码。

Java文档注释:

Java 文档注释(也称为 Javadoc 注释)是 Java 特有的一种注释方式,用于生成 API 文档。Javadoc 是 Sun Microsystems(现在是 Oracle)提供的一种工具,它可以解析源代码中的特殊注释,生成 HTML 格式的文档。这些文档通常包括类、接口、方法和字段的详细说明,帮助开发者更好地理解和使用代码。更多文档注释的内容可以参考:Java 文档注释

实例

下面是一个使用说明注释的简单实例。注意每一个注释都在它描述的项目的前面。

在经过 javadoc 处理之后,SquareNum 类的注释将在 SquareNum.html 中找到。

import java.io.*;
 
/**
* 这个类演示了文档注释
* @author Ayan Amhed
* @version 1.2
*/
public class SquareNum {
   /**
   * This method returns the square of num.
   * This is a multiline description. You can use
   * as many lines as you like.
   * @param num The value to be squared.
   * @return num squared.
   */
   public double square(double num) {
      return num * num;
   }
   /**
   * This method inputs a number from the user.
   * @return The value input as a double.
   * @exception IOException On input error.
   * @see IOException
   */
   public double getNumber() throws IOException {
      InputStreamReader isr = new InputStreamReader(System.in);
      BufferedReader inData = new BufferedReader(isr);
      String str;
      str = inData.readLine();
      return (new Double(str)).doubleValue();
   }
   /**
   * This method demonstrates square().
   * @param args Unused.
   * @return Nothing.
   * @exception IOException On input error.
   * @see IOException
   */
   public static void main(String args[]) throws IOException
   {
      SquareNum ob = new SquareNum();
      double val;
      System.out.println("Enter value to be squared: ");
      val = ob.getNumber();
      val = ob.square(val);
      System.out.println("Squared value is " + val);
   }
}

Java对象和类★★★★★★

Java 作为一种面向对象的编程语言,支持以下基本概念:

1、类(Class)

  • 定义对象的蓝图,包括属性和方法。
  • 示例:public class Car { ... }

2、对象(Object)

  • 类的实例,具有状态和行为。
  • 示例:Car myCar = new Car();

3、继承(Inheritance)

  • 一个类可以继承另一个类的属性和方法。
  • 示例:public class Dog extends Animal { ... }

4、封装(Encapsulation)

  • 将对象的状态(字段)私有化,通过公共方法访问。
  • 示例:
    private String name; 
    public String getName() { return name; }

5、多态(Polymorphism)

  • 对象可以表现为多种形态,主要通过方法重载和方法重写实现。
  • 示例:
    • 方法重载:public int add(int a, int b) { ... } 和 public double add(double a, double b) { ... }
    • 方法重写:@Override public void makeSound() { System.out.println("Meow"); }

6、抽象(Abstraction)

  • 使用抽象类和接口来定义必须实现的方法,不提供具体实现。
  • 示例:
    • 抽象类:public abstract class Shape { abstract void draw(); }
    • 接口:public interface Animal { void eat(); }

7、接口(Interface)

  • 定义类必须实现的方法,支持多重继承。
  • 示例:public interface Drivable { void drive(); }

8、方法(Method)

  • 定义类的行为,包含在类中的函数。
  • 示例:public void displayInfo() { System.out.println("Info"); }

9、方法重载(Method Overloading)

  • 同一个类中可以有多个同名的方法,但参数不同。
  • 示例:
public class MathUtils {
    public int add(int a, int b) {
        return a + b;
    }

    public double add(double a, double b) {
        return a + b;
    }
}

问:Java的public static void main是他的主类吗

答:在 Java 中,public static void main 方法并不是“主类”,而是程序的入口点。每个 Java 应用程序都必须有一个 main 方法,这是 JVM(Java 虚拟机)启动程序的地方。

main 方法的定义

public static void main(String[] args) {
    // 程序的起点
}
  • public:访问修饰符,表示该方法对所有类可见。
  • static:静态修饰符,表示该方法属于类本身,而不是类的实例。因此,可以在没有创建类的实例的情况下调用该方法。
  • void:返回类型,表示该方法不返回任何值。
  • main:方法名,必须是 main,这是 JVM 规定的。
  • String[] args:参数列表,通常用于接收命令行参数。
  1. 主类:包含 main 方法的类被称为主类。主类是程序的起点。
  2. 命名:主类的名称通常与包含它的文件名相同。例如,如果主类名为 MyApp,则文件名应为 MyApp.java。

一个Java 程序是指一个可以独立运行的单元,这个单元必须包含一个 main 方法作为程序的入口点。一个完整的 Java 程序是以 public static void main(String[] args) 方法为标志的。这个方法是 Java 虚拟机(JVM)启动程序的入口点。

构造方法

每个类都有构造方法。如果没有显式地为类定义构造方法,Java 编译器将会为该类提供一个默认构造方法。

在创建一个对象的时候,至少要调用一个构造方法。构造方法的名称必须与类同名,一个类可以有多个构造方法。下面是一个构造方法示例:

public class Puppy{
    public Puppy(){
    }
 
    public Puppy(String name){
        // 这个构造器仅有一个参数:name
    }
}

创建对象

对象是根据类创建的。在Java中,使用关键字 new 来创建一个新的对象。创建对象需要以下三步:

  • 声明:声明一个对象,包括对象名称和对象类型。
  • 实例化:使用关键字 new 来创建一个对象。
  • 初始化:使用 new 创建对象时,会调用构造方法初始化对象。

下面是一个创建对象的例子:

public class Puppy{
   public Puppy(String name){
      //这个构造器仅有一个参数:name
      System.out.println("小狗的名字是 : " + name ); 
   }
   public static void main(String[] args){
      // 下面的语句将创建一个Puppy对象
      Puppy myPuppy = new Puppy( "tommy" );
   }
}

实例

下面的例子展示如何访问实例变量和调用成员方法

public class Puppy {
    private int age;
    private String name;
 
    // 构造器
    public Puppy(String name) {
        this.name = name;
        System.out.println("小狗的名字是 : " + name);
    }
 
    // 设置 age 的值
    public void setAge(int age) {
        this.age = age;
    }
 
    // 获取 age 的值
    public int getAge() {
        return age;
    }
 
    // 获取 name 的值
    public String getName() {
        return name;
    }
 
    // 主方法
    public static void main(String[] args) {
        // 创建对象
        Puppy myPuppy = new Puppy("Tommy");
 
        // 通过方法来设定 age
        myPuppy.setAge(2);
 
        // 调用另一个方法获取 age
        int age = myPuppy.getAge();
        System.out.println("小狗的年龄为 : " + age);
 
        // 也可以直接访问成员变量(通过 getter 方法)
        System.out.println("变量值 : " + myPuppy.getAge());
    }
}

源文件声明规则

在本节的最后部分,我们将学习源文件的声明规则。当在一个源文件中定义多个类,并且还有import语句和package语句时,要特别注意这些规则。

  • 一个源文件中只能有一个 public 类
  • 一个源文件可以有多个非 public 类
  • 源文件的名称应该和 public 类的类名保持一致。例如:源文件中 public 类的类名是 Employee,那么源文件应该命名为Employee.java。
  • 如果一个类定义在某个包中,那么 package 语句应该在源文件的首行。
  • 如果源文件包含 import 语句,那么应该放在 package 语句和类定义之间。如果没有 package 语句,那么 import 语句应该在源文件中最前面。
  • import 语句和 package 语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

类有若干种访问级别,并且类也分不同的类型:抽象类和 final 类等。这些将在访问控制章节介绍。除了上面提到的几种类型,Java 还有一些特殊的类,如:内部类匿名类

Java 包

包主要用来对类和接口进行分类。当开发 Java 程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类。

import 语句

在 Java 中,如果给出一个完整的限定名,包括包名、类名,那么 Java 编译器就可以很容易地定位到源代码或者类。import 语句就是用来提供一个合理的路径,使得编译器可以找到某个类。

例如,下面的命令行将会命令编译器载入 java_installation/java/io 路径下的所有类

import java.io.*;

一个简单的例子

(至于简单与否,看你的水平了)在该例子中,我们创建两个类:Employee 和 EmployeeTest。Employee 类有四个成员变量:name、age、designation 和 salary,该类显式声明了一个构造方法,该方法只有一个参数。

import java.io.*;
 
public class Employee {
    private String name;
    private int age;
    private String designation;
    private double salary;
 
    // Employee 类的构造器
    public Employee(String name) {
        this.name = name;
    }
 
    // 设置 age 的值
    public void setAge(int age) {
        this.age = age;
    }
 
    // 获取 age 的值
    public int getAge() {
        return age;
    }
 
    // 设置 designation 的值
    public void setDesignation(String designation) {
        this.designation = designation;
    }
 
    // 获取 designation 的值
    public String getDesignation() {
        return designation;
    }
 
    // 设置 salary 的值
    public void setSalary(double salary) {
        this.salary = salary;
    }
 
    // 获取 salary 的值
    public double getSalary() {
        return salary;
    }
 
    // 打印信息
    public void printEmployee() {
        System.out.println(this);
    }
 
    // 重写 toString 方法
    @Override
    public String toString() {
        return "名字: " + name + "\n" +
               "年龄: " + age + "\n" +
               "职位: " + designation + "\n" +
               "薪水: " + salary;
    }
}

Java 程序都是从 main 方法开始执行,为了能运行这个程序,必须包含 main 方法并且创建一个实例对象。下面给出 EmployeeTest 类,该类实例化 2 个 Employee 类的实例,并调用方法设置变量的值。将下面的代码保存在 EmployeeTest.java文件中。

import java.io.*;
 
public class EmployeeTest {
    public static void main(String[] args) {
        // 使用构造器创建两个对象
        Employee empOne = new Employee("RUNOOB1");
        Employee empTwo = new Employee("RUNOOB2");
 
        // 调用这两个对象的成员方法
        empOne.setAge(26);
        empOne.setDesignation("高级程序员");
        empOne.setSalary(1000);
        empOne.printEmployee();
 
        empTwo.setAge(21);
        empTwo.setDesignation("菜鸟程序员");
        empTwo.setSalary(500);
        empTwo.printEmployee();
    }
}

//    编译这两个文件并且运行 EmployeeTest 类,可以看到如下结果:
//    $ javac EmployeeTest.java Employee.java
//        $ java EmployeeTest
//        名字:RUNOOB1
//        年龄:26
//        职位:高级程序员
//        薪水:1000.0
//        名字:RUNOOB2
//        年龄:21
//        职位:菜鸟程序员
//        薪水:500.0

Java基本数据类型★★★

内置数据类型

Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型)(byte、short、int、long、float、double),一种字符类型,还有一种布尔型。(char、boolean)

实例:

对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。请看下面的例子:

public class PrimitiveTypeTest {  
    public static void main(String[] args) {  
        // byte  
        System.out.println("基本类型:byte 二进制位数:" + Byte.SIZE);  
        System.out.println("包装类:java.lang.Byte");  
        System.out.println("最小值:Byte.MIN_VALUE=" + Byte.MIN_VALUE);  
        System.out.println("最大值:Byte.MAX_VALUE=" + Byte.MAX_VALUE);  
        System.out.println();  
  
        // short  
        System.out.println("基本类型:short 二进制位数:" + Short.SIZE);  
        System.out.println("包装类:java.lang.Short");  
        System.out.println("最小值:Short.MIN_VALUE=" + Short.MIN_VALUE);  
        System.out.println("最大值:Short.MAX_VALUE=" + Short.MAX_VALUE);  
        System.out.println();  
  
        // int  
        System.out.println("基本类型:int 二进制位数:" + Integer.SIZE);  
        System.out.println("包装类:java.lang.Integer");  
        System.out.println("最小值:Integer.MIN_VALUE=" + Integer.MIN_VALUE);  
        System.out.println("最大值:Integer.MAX_VALUE=" + Integer.MAX_VALUE);  
        System.out.println();  
  
        // long  
        System.out.println("基本类型:long 二进制位数:" + Long.SIZE);  
        System.out.println("包装类:java.lang.Long");  
        System.out.println("最小值:Long.MIN_VALUE=" + Long.MIN_VALUE);  
        System.out.println("最大值:Long.MAX_VALUE=" + Long.MAX_VALUE);  
        System.out.println();  
  
        // float  
        System.out.println("基本类型:float 二进制位数:" + Float.SIZE);  
        System.out.println("包装类:java.lang.Float");  
        System.out.println("最小值:Float.MIN_VALUE=" + Float.MIN_VALUE);  
        System.out.println("最大值:Float.MAX_VALUE=" + Float.MAX_VALUE);  
        System.out.println();  
  
        // double  
        System.out.println("基本类型:double 二进制位数:" + Double.SIZE);  
        System.out.println("包装类:java.lang.Double");  
        System.out.println("最小值:Double.MIN_VALUE=" + Double.MIN_VALUE);  
        System.out.println("最大值:Double.MAX_VALUE=" + Double.MAX_VALUE);  
        System.out.println();  
  
        // char  
        System.out.println("基本类型:char 二进制位数:" + Character.SIZE);  
        System.out.println("包装类:java.lang.Character");  
        // 以数值形式而不是字符形式将Character.MIN_VALUE输出到控制台  
        System.out.println("最小值:Character.MIN_VALUE="  
                + (int) Character.MIN_VALUE);  
        // 以数值形式而不是字符形式将Character.MAX_VALUE输出到控制台  
        System.out.println("最大值:Character.MAX_VALUE="  
                + (int) Character.MAX_VALUE);  
    }  
}


// 理应输出为:

// 基本类型:byte 二进制位数:8
// 包装类:java.lang.Byte
// 最小值:Byte.MIN_VALUE=-128
// 最大值:Byte.MAX_VALUE=127

// 基本类型:short 二进制位数:16
// 包装类:java.lang.Short
// 最小值:Short.MIN_VALUE=-32768
// 最大值:Short.MAX_VALUE=32767

// 基本类型:int 二进制位数:32
// 包装类:java.lang.Integer
// 最小值:Integer.MIN_VALUE=-2147483648
// 最大值:Integer.MAX_VALUE=2147483647

// 基本类型:long 二进制位数:64
// 包装类:java.lang.Long
// 最小值:Long.MIN_VALUE=-9223372036854775808
// 最大值:Long.MAX_VALUE=9223372036854775807

// 基本类型:float 二进制位数:32
// 包装类:java.lang.Float
// 最小值:Float.MIN_VALUE=1.4E-45
// 最大值:Float.MAX_VALUE=3.4028235E38

// 基本类型:double 二进制位数:64
// 包装类:java.lang.Double
// 最小值:Double.MIN_VALUE=4.9E-324
// 最大值:Double.MAX_VALUE=1.7976931348623157E308

// 基本类型:char 二进制位数:16
// 包装类:java.lang.Character
// 最小值:Character.MIN_VALUE=0
// 最大值:Character.MAX_VALUE=65535

引用类型

  • 在Java中,引用类型的变量非常类似于C/C++的指针。引用类型指向一个对象,指向对象的变量是引用变量。这些变量在声明时被指定为一个特定的类型,比如 Employee、Puppy 等。变量一旦声明后,类型就不能被改变了。
  • 对象、数组都是引用数据类型。
  • 所有引用类型的默认值都是null。
  • 一个引用变量可以用来引用任何与之兼容的类型。
  • 例子:Site site = new Site("Runoob")。

Java 常量

常量在程序运行时是不能被修改的。在 Java 中使用 final 关键字来修饰常量,声明方式和变量类似:(为了便于识别,通常使用大写字母表示常量。)

final double PI = 3.1415927;

类型转换 

Java变量类型★★★★

Java 语言支持的变量类型有:

  • 局部变量(Local Variables):局部变量是在方法、构造函数或块内部声明的变量,它们在声明的方法、构造函数或块执行结束后被销毁,局部变量在声明时需要初始化,否则会导致编译错误。
  • 实例变量(Instance Variables):实例变量是在类中声明,但在方法、构造函数或块之外,它们属于类的实例,每个类的实例都有自己的副本,如果不明确初始化,实例变量会被赋予默认值(数值类型为0,boolean类型为false,对象引用类型为null)。(有点像C语言的全局变量,只是因为Java程序,是以类为单位的)
  • 静态变量或类变量(Class Variables):类变量是在类中用 static 关键字声明的变量,它们属于类而不是实例,所有该类的实例共享同一个类变量的值,类变量在类加载时被初始化,而且只初始化一次。
  • 参数变量(Parameters):参数是方法或构造函数声明中的变量,用于接收调用该方法或构造函数时传递的值,参数变量的作用域只限于方法内部。

成员变量和实例变量这两个术语在某些情况下被互换使用,主要是因为它们之间存在重叠,而且在很多实际应用中,成员变量通常指的是实例变量。不过,严格来说,它们是有区别的。成员变量包括实例变量 和 静态变量。实例:

public class RunoobTest {
    // 成员变量
    private int instanceVar;
    // 静态变量
    private static int staticVar;
    
    public void method(int paramVar) {
        // 局部变量
        int localVar = 10;
        
        // 使用变量
        instanceVar = localVar;
        staticVar = paramVar;
        
        System.out.println("成员变量: " + instanceVar);
        System.out.println("静态变量: " + staticVar);
        System.out.println("参数变量: " + paramVar);
        System.out.println("局部变量: " + localVar);
    }
    
    public static void main(String[] args) {
        RunoobTest v = new RunoobTest();
        v.method(20);
    }
}

类变量………… 

Java变量命名规则★

驼峰命名法

// 使用驼峰命名法
public static int myStaticVariable;

// 使用大写蛇形命名法
public static final int MAX_SIZE = 100;

Java修饰符★★★★★

访问修饰符(public、private、protected、default)

非访问修饰符(static、final、abstract、synchronized、transient、volatile)

访问控制修饰符

Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

  • public : 对所有类可见。使用对象:类、接口、变量、方法

  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

我们可以通过以下表来说明访问权限:

访问控制
修饰符当前类同一包内子孙类(同一包)子孙类(不同包)其他包
publicYYYYY
protectedYYYY/N(说明N
defaultYYYNN
privateYNNNN

默认访问修饰符-不使用任何关键字

如果在类、变量、方法或构造函数的定义中没有指定任何访问修饰符,那么它们就默认具有默认访问修饰符。默认访问修饰符的访问级别是包级别(package-level),即只能被同一包中的其他类访问。如下例所示,变量和方法的声明可以不使用任何修饰符。

// MyClass.java
 
class MyClass {  // 默认访问修饰符
 
    int x = 10;  // 默认访问修饰符
 
    void display() {  // 默认访问修饰符
        System.out.println("Value of x is: " + x);
    }
}
 
// MyOtherClass.java
 
class MyOtherClass {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.display();  // 访问 MyClass 中的默认访问修饰符变量和方法
    }
}

以上实例中,MyClass 类和它的成员变量 x 和方法 display() 都使用默认访问修饰符进行了定义。MyOtherClass 类在同一包中,因此可以访问 MyClass 类和它的成员变量和方法。 

protected 是最难理解的一种 Java 类成员访问权限修饰词,更多详细内容请查看 Java protected 关键字详解

访问控制和继承

请注意以下方法继承的规则:

  • 父类中声明为 public 的方法在子类中也必须为 public。

  • 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。

  • 父类中声明为 private 的方法,不能够被子类继承。

非访问修饰符

为了实现一些其他的功能,Java 也提供了许多非访问修饰符。

  • static 修饰符,用来修饰类方法和类变量。
  • final 修饰符,用来修饰类、方法和变量,final 修饰的类不能够被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,是不可修改的。
  • abstract 修饰符,用来创建抽象类和抽象方法。
  • synchronized 和 volatile 修饰符,主要用于线程的编程。
static 修饰符
  • 静态变量:

    static 关键字用来声明独立于对象的静态变量,无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。

  • 静态方法:

    static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。

final 修饰符

final 变量:

final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。(之前提到的常量,就是使用final)

final 修饰符通常和 static 修饰符一起使用来创建类常量

public class Test{
  final int value = 10;
  // 下面是声明常量的实例
  public static final int BOXWIDTH = 6;
  static final String TITLE = "Manager";
 
  public void changeValue(){
     value = 12; //将输出一个错误
  }
}

final 方法

父类中的 final 方法可以被子类继承,但是不能被子类重写。声明 final 方法的主要目的是防止该方法的内容被修改。

如下所示,使用 final 修饰符声明方法。

public class Test{
    public final void changeName(){
       // 方法体
    }
}

final 类

final 类不能被继承,没有类能够继承 final 类的任何特性。

public final class Test {
   // 类体
}
abstract 修饰符

抽象类:

抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。抽象类可以包含抽象方法和非抽象方法

abstract class Caravan{
   private double price;
   private String model;
   private String year;
   public abstract void goFast(); //抽象方法
   public abstract void changeColor(); // 抽象方法
}

抽象方法

抽象方法是一种没有任何实现的方法,该方法的具体实现由子类提供

抽象方法不能被声明成 final 和 static。任何继承抽象类的子类必须实现父类的所有抽象方法,除非该子类也是抽象类。如果一个类包含若干个抽象方法,那么该类必须声明为抽象类。抽象类可以不包含抽象方法。抽象方法的声明以分号结尾,例如:public abstract sample();

public abstract class SuperClass{
    abstract void m(); //抽象方法
}
 
class SubClass extends SuperClass{
     //实现抽象方法
      void m(){
          .........
      }
}

synchronized 修饰符

synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。

transient 修饰符

序列化的对象包含被 transient 修饰的实例变量时,java 虚拟机(JVM)跳过该特定的变量。该修饰符包含在定义变量的语句中,用来预处理类和变量的数据类型。

volatile 修饰符

volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值。而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

一个 volatile 对象引用可能是 null。

Java运算符★★

Java位运算符★

位运算符

Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型(byte)等类型。

位运算符作用在所有的位上,并且按位运算。假设a = 60,b = 13;它们的二进制格式表示将如下

A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011

下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:

操作符描述例子
如果相对应位都是1,则结果为1,否则为0(A&B),得到12,即0000 1100
|如果相对应位都是 0,则结果为 0,否则为 1(A | B)得到61,即 0011 1101
^如果相对应位值相同,则结果为0,否则为1(A ^ B)得到49,即 0011 0001
按位取反运算符翻转操作数的每一位,即0变成1,1变成0。(〜A)得到-61,即1100 0011
<< 按位左移运算符。左操作数按位左移右操作数指定的位数。A << 2得到240,即 1111 0000
>> 按位右移运算符。左操作数按位右移右操作数指定的位数。A >> 2得到15即 1111
>>> 按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。A>>>2得到15即0000 1111

逻辑运算符

&&都为真,才是真;都为假,才是假。

instanceof 运算符

该运算符用于操作对象实例,检查该对象是否是一个特定类型(类类型或接口类型)。

instanceof运算符使用格式如下:

String name = "James";
boolean result = name instanceof String;
// 由于 name 是 String 类型,所以返回真

如果被比较的对象兼容于右侧类型,该运算符仍然返回 true。

class Vehicle {}
 
public class Car extends Vehicle {
   public static void main(String[] args){
      Vehicle a = new Car();
      boolean result =  a instanceof Car;
      System.out.println( result);
   }
}

运算符优先级:

Java循环结构

Java中有三种主要的循环结构:(不过多赘述)

  • while 循环
  • do…while 循环
  • for 循环

Java 增强 for 循环

public class Test {
   public static void main(String[] args){
      int [] numbers = {10, 20, 30, 40, 50};
 
      for(int x : numbers ){
         System.out.print( x );
         System.out.print(",");
      }
      System.out.print("\n");
      String [] names ={"James", "Larry", "Tom", "Lacy"};
      for( String name : names ) {
         System.out.print( name );
         System.out.print(",");
      }
   }
}

// 输出:
// 10,20,30,40,50,
// James,Larry,Tom,Lacy,

break、continue关键字

  • break:跳出循环
  • continue:跳过本次迭代

Java条件语句

if-else语句(略)

Java switch-case

如果 case 语句块中没有 break 语句时,匹配成功后,从当前 case 开始,后续所有 case 的值都会输出。

public class Test {
   public static void main(String args[]){
      int i = 1;
      switch(i){
         case 0:
            System.out.println("0");
         case 1: // i = 1,通过case,但由于没有break,后面的case都会运行
            System.out.println("1");
         case 2:
            System.out.println("2");
         default:
            System.out.println("default");
      }
   }
}

// 输出:
// 1
// 2
// default

Java Number & Math 类

Java Math 类

Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。

public class Test {  
    public static void main (String []args)  
    {  
        System.out.println("90 度的正弦值:" + Math.sin(Math.PI/2));  
        System.out.println("0度的余弦值:" + Math.cos(0));  
        System.out.println("60度的正切值:" + Math.tan(Math.PI/3));  
        System.out.println("1的反正切值: " + Math.atan(1));  
        System.out.println("π/2的角度值:" + Math.toDegrees(Math.PI/2));  
        System.out.println(Math.PI);  
    }  
}

Number & Math 类方法

下面的表中列出的是 Number & Math 类常用的一些方法:

public class NumberAndMathMethodsDemo {
    public static void main(String[] args) {
        // 1. xxxValue() - 将 Number 对象转换为指定的数据类型
        Double d = new Double("100.5");
        double value = d.doubleValue();
        System.out.println("doubleValue: " + value); // 输出: 100.5

        // 2. compareTo() - 比较两个 Number 对象
        Integer num1 = 10;
        Integer num2 = 20;
        int result = num1.compareTo(num2);  // 大于 输出1,等于 输出0
        System.out.println("compareTo: " + result); // 输出: -1 (num1 < num2)

        // 3. equals() - 判断两个 Number 对象是否相等
        Integer num3 = 10;
        boolean isEqual = num1.equals(num3);
        System.out.println("equals: " + isEqual); // 输出: true

        // 4. valueOf() - 返回指定字符串的 Number 对象
        String strNum = "123";
        Integer num4 = Integer.valueOf(strNum);
        System.out.println("valueOf: " + num4); // 输出: 123

        // 5. toString() - 将 Number 对象转换为字符串
        String strNum2 = num4.toString();
        System.out.println("toString: " + strNum2); // 输出: "123"

        // 6. parseInt() - 将字符串解析为 int 类型
        int parsedInt = Integer.parseInt(strNum);
        System.out.println("parseInt: " + parsedInt); // 输出: 123

        // 7. abs() - 返回参数的绝对值
        int absValue = Math.abs(-20);
        System.out.println("abs: " + absValue); // 输出: 20

        // 8. ceil() - 返回大于等于给定参数的最小整数(双精度浮点型)
        double ceilValue = Math.ceil(10.1);
        System.out.println("ceil: " + ceilValue); // 输出: 11.0

        // 9. floor() - 返回小于等于给定参数的最大整数
        double floorValue = Math.floor(10.9);
        System.out.println("floor: " + floorValue); // 输出: 10.0

        // 10. rint() - 返回与参数最接近的整数(双精度浮点型)
        double rintValue = Math.rint(10.5);
        System.out.println("rint: " + rintValue); // 输出: 10.0

        // 11. round() - 四舍五入,返回最接近的整数
        long roundValue = Math.round(10.5);
        System.out.println("round: " + roundValue); // 输出: 11

        // 12. min() - 返回两个参数中的最小值
        int minValue = Math.min(10, 20);
        System.out.println("min: " + minValue); // 输出: 10

        // 13. max() - 返回两个参数中的最大值
        int maxValue = Math.max(10, 20);
        System.out.println("max: " + maxValue); // 输出: 20

        // 14. exp() - 返回自然数 e 的参数次方
        double expValue = Math.exp(1);
        System.out.println("exp: " + expValue); // 输出: 2.718281828459045

        // 15. log() - 返回参数的自然对数值
        double logValue = Math.log(10);
        System.out.println("log: " + logValue); // 输出: 2.302585092994046

        // 16. pow() - 返回第一个参数的第二个参数次方
        double powValue = Math.pow(2, 3);
        System.out.println("pow: " + powValue); // 输出: 8.0

        // 17. sqrt() - 求参数的算术平方根
        double sqrtValue = Math.sqrt(16);
        System.out.println("sqrt: " + sqrtValue); // 输出: 4.0

        // 18. sin() - 求指定 double 类型参数的正弦值
        double sinValue = Math.sin(Math.PI / 2);
        System.out.println("sin: " + sinValue); // 输出: 1.0

        // 19. cos() - 求指定 double 类型参数的余弦值
        double cosValue = Math.cos(0);
        System.out.println("cos: " + cosValue); // 输出: 1.0

        // 20. tan() - 求指定 double 类型参数的正切值
        double tanValue = Math.tan(Math.PI / 4);
        System.out.println("tan: " + tanValue); // 输出: 0.9999999999999999

        // 21. asin() - 求指定 double 类型参数的反正弦值
        double asinValue = Math.asin(1);
        System.out.println("asin: " + asinValue); // 输出: 1.5707963267948966

        // 22. acos() - 求指定 double 类型参数的反余弦值
        double acosValue = Math.acos(0);
        System.out.println("acos: " + acosValue); // 输出: 1.5707963267948966

        // 23. atan() - 求指定 double 类型参数的反正切值
        double atanValue = Math.atan(1);
        System.out.println("atan: " + atanValue); // 输出: 0.7853981633974483

        // 24. atan2() - 将笛卡尔坐标转换为极坐标,并返回极坐标的角度值
        double atan2Value = Math.atan2(1, 1);
        System.out.println("atan2: " + atan2Value); // 输出: 0.7853981633974483

        // 25. toDegrees() - 将参数从弧度转换为角度
        double degreesValue = Math.toDegrees(Math.PI);
        System.out.println("toDegrees: " + degreesValue); // 输出: 180.0

        // 26. toRadians() - 将角度转换为弧度
        double radiansValue = Math.toRadians(180);
        System.out.println("toRadians: " + radiansValue); // 输出: 3.141592653589793

        // 27. random() - 返回一个随机数
        double randomValue = Math.random();
        System.out.println("random: " + randomValue); // 输出: 随机数,例如: 0.23456789
    }
}

Java Character 类

Character 方法

下面是Character类的方法:(对于方法的完整列表,请参考的 java.lang.Character API 规范。)

public class CharacterMethodsDemo {
    public static void main(String[] args) {
        // 定义一些字符用于测试
        char letterA = 'A';
        char digit5 = '5';
        char space = ' ';
        char lettera = 'a';
        char specialChar = '!';

        // 1. isLetter() - 判断是否是一个字母
        boolean isLetterA = Character.isLetter(letterA);
        System.out.println("isLetter('A'): " + isLetterA); // 输出: true

        boolean isLetter5 = Character.isLetter(digit5);
        System.out.println("isLetter('5'): " + isLetter5); // 输出: false

        // 2. isDigit() - 判断是否是一个数字字符
        boolean isDigit5 = Character.isDigit(digit5);
        System.out.println("isDigit('5'): " + isDigit5); // 输出: true

        boolean isDigitA = Character.isDigit(letterA);
        System.out.println("isDigit('A'): " + isDigitA); // 输出: false

        // 3. isWhitespace() - 判断是否是一个空白字符
        boolean isWhitespaceSpace = Character.isWhitespace(space);
        System.out.println("isWhitespace(' '): " + isWhitespaceSpace); // 输出: true

        boolean isWhitespaceA = Character.isWhitespace(letterA);
        System.out.println("isWhitespace('A'): " + isWhitespaceA); // 输出: false

        // 4. isUpperCase() - 判断是否是大写字母
        boolean isUpperCaseA = Character.isUpperCase(letterA);
        System.out.println("isUpperCase('A'): " + isUpperCaseA); // 输出: true

        boolean isUpperCasea = Character.isUpperCase(lettera);
        System.out.println("isUpperCase('a'): " + isUpperCasea); // 输出: false

        // 5. isLowerCase() - 判断是否是小写字母
        boolean isLowerCasea = Character.isLowerCase(lettera);
        System.out.println("isLowerCase('a'): " + isLowerCasea); // 输出: true

        boolean isLowerCaseA = Character.isLowerCase(letterA);
        System.out.println("isLowerCase('A'): " + isLowerCaseA); // 输出: false

        // 6. toUpperCase() - 转换为大写字母
        char upperCaseA = Character.toUpperCase(lettera);
        System.out.println("toUpperCase('a'): " + upperCaseA); // 输出: A

        char upperCaseSpecial = Character.toUpperCase(specialChar);
        System.out.println("toUpperCase('!'): " + upperCaseSpecial); // 输出: !

        // 7. toLowerCase() - 转换为小写字母
        char lowerCaseA = Character.toLowerCase(letterA);
        System.out.println("toLowerCase('A'): " + lowerCaseA); // 输出: a

        char lowerCaseSpecial = Character.toLowerCase(specialChar);
        System.out.println("toLowerCase('!'): " + lowerCaseSpecial); // 输出: !

        // 8. toString() - 返回字符的字符串形式
        String stringA = Character.toString(letterA);
        System.out.println("toString('A'): " + stringA); // 输出: A

        String stringSpace = Character.toString(space);
        System.out.println("toString(' '): " + stringSpace); // 输出: " "
    }
}

Java String 类★★★★★★

字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。

创建字符串

创建字符串最简单的方式如下:

String str = "Runoob";

在代码中遇到字符串常量时,这里的值是 "Runoob",编译器会使用该值创建一个 String 对象。和其它对象一样,可以使用关键字和构造方法来创建 String 对象。用构造函数创建字符串:

String str2=new String("Runoob");

String 创建的字符串存储在公共池中,而 new 创建的字符串对象在堆上:

String s1 = "Runoob";              // String 直接创建
String s2 = "Runoob";              // String 直接创建
String s3 = s1;                    // 相同引用
String s4 = new String("Runoob");   // String 对象创建
String s5 = new String("Runoob");   // String 对象创建

String 类有 11 种构造方法,这些方法提供不同的参数来初始化字符串,比如提供一个字符数组参数:

public class StringDemo{
   public static void main(String args[]){
      char[] helloArray = { 'r', 'u', 'n', 'o', 'o', 'b'};
      String helloString = new String(helloArray);  
      System.out.println( helloString );
   }
}

注意:String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了(详看笔记部分解析)。如果需要对字符串做很多修改,那么应该选择使用 StringBuffer & StringBuilder 类

字符串长度★★

用于获取有关对象的信息的方法称为访问器方法。String 类的一个访问器方法是 length() 方法,它返回字符串对象包含的字符数。下面的代码执行后,len 变量等于 14:

public class StringDemo {
    public static void main(String args[]) {
        String site = "www.runoob.com";
        int len = site.length();
        System.out.println( "菜鸟教程网址长度 : " + len );
   }
}

创建格式化字符串

(专业术语唬人的,理解下面代码就行,嘻嘻。有C语言基础的会很好理解)我们知道输出格式化数字可以使用 printf() 和 format() 方法。

String 类使用静态方法 format() 返回一个String 对象而不是 PrintStream 对象。

String 类的静态方法 format() 能用来创建可复用的格式化字符串,而不仅仅是用于一次打印输出。

System.out.printf("浮点型变量的值为 " +
                  "%f, 整型变量的值为 " +
                  " %d, 字符串变量的值为 " +
                  "is %s", floatVar, intVar, stringVar);

你也可以这样写

String fs;
fs = String.format("浮点型变量的值为 " +
                   "%f, 整型变量的值为 " +
                   " %d, 字符串变量的值为 " +
                   " %s", floatVar, intVar, stringVar);

String 方法★★★★★

下面是 String 类支持的方法,更多详细,参看 Java String API 文档:

SN(序号)方法描述
1char charAt(int index)
返回指定索引处的 char 值。
2int compareTo(Object o)
把这个字符串和另一个对象比较。
3int compareTo(String anotherString)
按字典顺序比较两个字符串。
4int compareToIgnoreCase(String str)
按字典顺序比较两个字符串,不考虑大小写。
5String concat(String str)
将指定字符串连接到此字符串的结尾。
6boolean contentEquals(StringBuffer sb)
当且仅当字符串与指定的StringBuffer有相同顺序的字符时候返回真。
7static String copyValueOf(char[] data)
返回指定数组中表示该字符序列的 String。
8static String copyValueOf(char[] data, int offset, int count)
返回指定数组中表示该字符序列的 String。
9boolean endsWith(String suffix)
测试此字符串是否以指定的后缀结束。
10boolean equals(Object anObject)
将此字符串与指定的对象比较。
11boolean equalsIgnoreCase(String anotherString)
将此 String 与另一个 String 比较,不考虑大小写。
12byte[] getBytes()
 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
13byte[] getBytes(String charsetName)
使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
14void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
将字符从此字符串复制到目标字符数组。
15int hashCode()
返回此字符串的哈希码。
16int indexOf(int ch)
返回指定字符在此字符串中第一次出现处的索引。
17int indexOf(int ch, int fromIndex)
返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
18int indexOf(String str)
 返回指定子字符串在此字符串中第一次出现处的索引。
19int indexOf(String str, int fromIndex)
返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
20String intern()
 返回字符串对象的规范化表示形式。
21int lastIndexOf(int ch)
 返回指定字符在此字符串中最后一次出现处的索引。
22int lastIndexOf(int ch, int fromIndex)
返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
23int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引。
24int lastIndexOf(String str, int fromIndex)
 返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
25int length()
返回此字符串的长度。
26boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式。
27boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
测试两个字符串区域是否相等。
28boolean regionMatches(int toffset, String other, int ooffset, int len)
测试两个字符串区域是否相等。
29String replace(char oldChar, char newChar)
返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的。
30String replaceAll(String regex, String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
31String replaceFirst(String regex, String replacement)
 使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
32String[] split(String regex)
根据给定正则表达式的匹配拆分此字符串。
33String[] split(String regex, int limit)
根据匹配给定的正则表达式来拆分此字符串。
34boolean startsWith(String prefix)
测试此字符串是否以指定的前缀开始。
35boolean startsWith(String prefix, int toffset)
测试此字符串从指定索引开始的子字符串是否以指定前缀开始。
36CharSequence subSequence(int beginIndex, int endIndex)
 返回一个新的字符序列,它是此序列的一个子序列。
37String substring(int beginIndex)
返回一个新的字符串,它是此字符串的一个子字符串。
38String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串。
39char[] toCharArray()
将此字符串转换为一个新的字符数组。
40String toLowerCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
41String toLowerCase(Locale locale)
 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。
42String toString()
 返回此对象本身(它已经是一个字符串!)。
43String toUpperCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
44String toUpperCase(Locale locale)
使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。
45String trim()
返回字符串的副本,忽略前导空白和尾部空白。
46static String valueOf(primitive data type x)
返回给定data type类型x参数的字符串表示形式。
47contains(CharSequence chars)
判断是否包含指定的字符系列。
48isEmpty()
判断字符串是否为空。

Java StringBuffer 和 StringBuilder 类

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

在使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,所以如果需要对字符串进行修改推荐使用 StringBuffer。

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。(说明:和数组不一样,索引从1开始)

public class RunoobTest{
    public static void main(String[] args){
        StringBuilder sb = new StringBuilder(10);
        sb.append("Runoob..");
        System.out.println(sb);  
        sb.append("!");
        System.out.println(sb); 
        sb.insert(8, "Java");  // 在第8个后面插入
        System.out.println(sb); 
        sb.delete(5,8);  //  删除第6、7、8个
        System.out.println(sb);  
    }
}

//Runoob..
//Runoob..!
//Runoob..Java!
//RunooJava!

然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

public class Test{
  public static void main(String[] args){
    StringBuffer sBuffer = new StringBuffer("菜鸟教程官网:");
    sBuffer.append("www");
    sBuffer.append(".runoob");
    sBuffer.append(".com");
    System.out.println(sBuffer);  
  }
}

// 菜鸟教程官网:www.runoob.com

StringBuffer 方法

以下是 StringBuffer 类支持的主要方法:

序号方法描述
1public StringBuffer append(String s)
将指定的字符串追加到此字符序列。
2public StringBuffer reverse()
 将此字符序列用其反转形式取代。
3public delete(int start, int end)
移除此序列的子字符串中的字符。
4public insert(int offset, int i)
将 int 参数的字符串表示形式插入此序列中。
5insert(int offset, String str)
将 str 参数的字符串插入此序列中。
6replace(int start, int end, String str)
使用给定 String 中的字符替换此序列的子字符串中的字符。

更多内容:

Java 数组

创建数组:

public class TestArray {
   public static void main(String[] args) {
      // 定义数组
      double[] myList = {1.9, 2.9, 3.4, 3.5};
 
      // 打印所有数组元素
      for (int i = 0; i < myList.length; i++) {
         System.out.println(myList[i] + " ");
      }
      // 计算所有元素的总和
      double total = 0;
      for (int i = 0; i < myList.length; i++) {
         total += myList[i];
      }
      System.out.println("Total is " + total);
      // 查找最大元素
      double max = myList[0];
      for (int i = 1; i < myList.length; i++) {
         if (myList[i] > max) max = myList[i];
      }
      System.out.println("Max is " + max);
   }
}

数组作为函数的参数

数组可以作为参数传递给方法

例如,下面的例子就是一个打印 int 数组中元素的方法:

public static void printArray(int[] array) {
  for (int i = 0; i < array.length; i++) {
    System.out.print(array[i] + " ");
  }
}

下面例子调用 printArray 方法打印出 3,1,2,6,4 和 2:

printArray(new int[]{3, 1, 2, 6, 4, 2});

数组作为函数的返回值

public static int[] reverse(int[] list) {
  int[] result = new int[list.length];
 
  for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
    result[j] = list[i];
  }
  return result;
}

多维数组

String[][] str = new String[3][4];

String[][] s = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");

Arrays 类

java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。

具有以下功能:

  • 给数组赋值:通过 fill 方法。
  • 比较数组:通过 equals 方法比较数组中元素值是否相等。
  • 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
  • 对数组排序:通过 sort 方法,按升序。
import java.util.Arrays;

public class test {
    public static void main(String[] args) {
        // 定义一些数组用于测试
        int[] array1 = {3, 1, 4, 1, 5, 9};
        int[] array2 = {3, 1, 4, 1, 5, 9};
        int[] array3 = {2, 7, 1, 8, 2, 8};

        // 1. sort - 对指定对象数组根据其元素的自然顺序进行升序排列
        Arrays.sort(array1);
        System.out.println("sort: " + Arrays.toString(array1)); // 输出: [1, 1, 3, 4, 5, 9]

        // 2. binarySearch - 用二分查找算法在给定数组中搜索给定值的对象
        // 注意:在使用 binarySearch 之前,数组必须先排序
        int index = Arrays.binarySearch(array1, 4);
        System.out.println("binarySearch: " + index); // 输出: 3 (因为 4 在排序后的数组中的索引是 2)

        // 3. equals - 如果两个指定的 long 型数组彼此相等,则返回 true
        boolean isEqual = Arrays.equals(array1, array2);
        System.out.println("equals: " + isEqual); // 输出: true (因为 array1 和 array2 内容相同)

        boolean isNotEqual = Arrays.equals(array1, array3);
        System.out.println("equals: " + isNotEqual); // 输出: false (因为 array1 和 array3 内容不同)

        // 4. fill - 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素
        Arrays.fill(array3, 0, 3, 0); // 将 array3 的前 3 个元素填充为 0
        System.out.println("fill: " + Arrays.toString(array3)); // 输出: [0, 0, 0, 8, 2, 8]
    }
}

Java日期时间

Java正则表达式

Java方法

Java 流(Stream)、文件(File)和IO

Java 中的流(Stream)、文件(File)和 IO(输入输出)是处理数据读取和写入的基础设施,它们允许程序与外部数据(如文件、网络、系统输入等)进行交互。

java.io 包是 Java 标准库中的一个核心包,提供了用于系统输入和输出的类,它包含了处理数据流(字节流和字符流)、文件读写、序列化以及数据格式化的工具。

java.io 是处理文件操作、流操作以及低级别 IO 操作的基础包。

java.io 包中的流支持很多种格式,比如:基本类型、对象、本地化字符集等等。

一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。

读取控制台输入

Java 的控制台输入由 System.in 完成。

为了获得一个绑定到控制台的字符流,你可以把 System.in 包装在一个 BufferedReader 对象中来创建一个字符流。

下面是创建 BufferedReader 的基本语法:

BufferedReader br = new BufferedReader(new 
                      InputStreamReader(System.in));

BufferedReader 对象创建后,我们便可以使用 read() 方法从控制台读取一个字符,或者用 readLine() 方法读取一个字符串。

从控制台读取多字符输入

从 BufferedReader 对象读取一个字符要使用 read() 方法,它的语法如下:

int read( ) throws IOException

每次调用 read() 方法,它从输入流读取一个字符并把该字符作为整数值返回。 当流结束的时候返回 -1。该方法抛出 IOException。

下面的程序示范了用 read() 方法从控制台不断读取字符直到用户输入 q。

//使用 BufferedReader 在控制台读取字符
 
import java.io.*;
 
public class BRRead {
    public static void main(String[] args) throws IOException {
        char c;
        // 使用 System.in 创建 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("输入字符, 按下 'q' 键退出。");
        // 读取字符
        do {
            c = (char) br.read();
            System.out.println(c);
        } while (c != 'q');
    }
}

从控制台读取字符串

从标准输入读取一个字符串需要使用 BufferedReader 的 readLine() 方法。

下面的程序读取和显示字符行直到你输入了单词"end"。

//使用 BufferedReader 在控制台读取字符
import java.io.*;
 
public class BRReadLines {
    public static void main(String[] args) throws IOException {
        // 使用 System.in 创建 BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        System.out.println("Enter lines of text.");
        System.out.println("Enter 'end' to quit.");
        do {
            str = br.readLine();
            System.out.println(str);
        } while (!str.equals("end"));
    }
}

控制台输出

在此前已经介绍过,控制台的输出由 print( ) 和 println() 完成。这些方法都由类 PrintStream 定义,System.out 是该类对象的一个引用。

PrintStream 继承了 OutputStream类,并且实现了方法 write()。这样,write() 也可以用来往控制台写操作。

PrintStream 定义 write() 的最简单格式如下所示:

void write(int byteval)

该方法将 byteval 的低八位字节写到流中。

实例:

下面的例子用 write() 把字符 "A" 和紧跟着的换行符输出到屏幕:

import java.io.*;
 
//演示 System.out.write().
public class WriteDemo {
    public static void main(String[] args) {
        int b;
        b = 'A';
        System.out.write(b);
        System.out.write('\n');
    }
}

注意:write() 方法不经常使用,因为 print() 和 println() 方法用起来更为方便。

读写文件

如前所述,一个流被定义为一个数据序列。输入流用于从源读取数据,输出流用于向目标写数据。

下图是一个描述输入流和输出流的类层次图。

字节流(处理二进制数据)

字节流用于处理二进制数据,例如文件、图像、视频等。

类名类型描述
InputStream抽象类 (输入流)所有字节输入流的超类,处理字节的输入操作。
OutputStream抽象类 (输出流)所有字节输出流的超类,处理字节的输出操作。
FileInputStream输入流从文件中读取字节数据。
FileOutputStream输出流将字节数据写入文件。
BufferedInputStream输入流为字节输入流提供缓冲功能,提高读取效率。
BufferedOutputStream输出流为字节输出流提供缓冲功能,提高写入效率。
ByteArrayInputStream输入流将内存中的字节数组作为输入源。
ByteArrayOutputStream输出流将数据写入到内存中的字节数组。
DataInputStream输入流允许从输入流中读取 Java 原生数据类型(如 intfloatboolean)。
DataOutputStream输出流允许向输出流中写入 Java 原生数据类型。
ObjectInputStream输入流从输入流中读取序列化对象。
ObjectOutputStream输出流将对象序列化并写入输出流中。
PipedInputStream输入流用于在管道中读取字节数据,通常与 PipedOutputStream 配合使用。
PipedOutputStream输出流用于在管道中写入字节数据,通常与 PipedInputStream 配合使用。
FilterInputStream输入流字节输入流的包装类,用于对其他输入流进行过滤处理。
FilterOutputStream输出流字节输出流的包装类,用于对其他输出流进行过滤处理。
SequenceInputStream输入流将多个输入流串联为一个输入流进行处理。
字符流(处理文本数据)

字符流用于处理文本数据,例如读取和写入字符串或文件。

类名类型描述
Reader抽象类 (输入流)所有字符输入流的超类,处理字符的输入操作。
Writer抽象类 (输出流)所有字符输出流的超类,处理字符的输出操作。
FileReader输入流从文件中读取字符数据。
FileWriter输出流将字符数据写入文件。
BufferedReader输入流为字符输入流提供缓冲功能,支持按行读取,提高读取效率。
BufferedWriter输出流为字符输出流提供缓冲功能,支持按行写入,提高写入效率。
CharArrayReader输入流将字符数组作为输入源。
CharArrayWriter输出流将数据写入到字符数组。
StringReader输入流将字符串作为输入源。
StringWriter输出流将数据写入到字符串缓冲区。
PrintWriter输出流便捷的字符输出流,支持自动刷新和格式化输出。
PipedReader输入流用于在管道中读取字符数据,通常与 PipedWriter 配合使用。
PipedWriter输出流用于在管道中写入字符数据,通常与 PipedReader 配合使用。
LineNumberReader输入流带行号的缓冲字符输入流,允许跟踪读取的行号。
PushbackReader输入流允许在读取字符后将字符推回流中,以便再次读取。
辅助类(其他重要类)

辅助类提供对文件、目录以及随机文件访问的支持。

类名类型描述
File文件和目录操作用于表示文件或目录,并提供文件操作,如创建、删除、重命名等。
RandomAccessFile随机访问文件支持文件的随机访问,可以从文件的任意位置读写数据。
Console控制台输入输出提供对系统控制台的输入和输出支持。

下面将要讨论的两个重要的流是 FileInputStream 和 FileOutputStream

FileInputStream

该流用于从文件读取数据,它的对象可以用关键字 new 来创建。

有多种构造方法可用来创建对象。

可以使用字符串类型的文件名来创建一个输入流对象来读取文件:

InputStream f = new FileInputStream("C:/java/hello");

也可以使用一个文件对象来创建一个输入流对象来读取文件。我们首先得使用 File() 方法来创建一个文件对象:

File f = new File("C:/java/hello");
InputStream in = new FileInputStream(f);

创建了 InputStream 对象,就可以使用下面的方法来读取流或者进行其他的流操作。

方法描述示例代码
int read()读取一个字节的数据,返回值为 0 到 255 之间的整数。如果到达流的末尾,返回 -1。int data = inputStream.read();
int read(byte[] b)从输入流中读取字节,并将其存储在字节数组 b 中,返回实际读取的字节数。如果到达流的末尾,返回 -1。byte[] buffer = new byte[1024]; int bytesRead = inputStream.read(buffer);
int read(byte[] b, int off, int len)从输入流中读取最多 len 个字节,并将它们存储在字节数组 b 的 off 偏移位置,返回实际读取的字节数。如果到达流的末尾,返回 -1。byte[] buffer = new byte[1024]; int bytesRead = inputStream.read(buffer, 0, buffer.length);
long skip(long n)跳过并丢弃输入流中的 n 个字节,返回实际跳过的字节数。long skippedBytes = inputStream.skip(100);
int available()返回可以读取的字节数(不阻塞)。int availableBytes = inputStream.available();
void close()关闭输入流并释放与该流相关的所有资源。inputStream.close();
void mark(int readlimit)在流中的当前位置设置标记,readlimit 是可以读取的字节数上限。inputStream.mark(1024);
void reset()将流重新定位到上次标记的位置,如果没有标记或标记失效,抛出 IOExceptioninputStream.reset();
boolean markSupported()检查当前输入流是否支持 mark() 和 reset() 操作。boolean isMarkSupported = inputStream.markSupported();

除了 InputStream 外,还有一些其他的输入流,更多的细节参考下面链接:

FileOutputStream

该类用来创建一个文件并向文件中写数据。

如果该流在打开文件进行输出前,目标文件不存在,那么该流会创建该文件。

有两个构造方法可以用来创建 FileOutputStream 对象。

使用字符串类型的文件名来创建一个输出流对象:

OutputStream f = new FileOutputStream("C:/java/hello")

也可以使用一个文件对象来创建一个输出流来写文件。我们首先得使用File()方法来创建一个文件对象:

File f = new File("C:/java/hello");
OutputStream fOut = new FileOutputStream(f);

创建 OutputStream 对象完成后,就可以使用下面的方法来写入流或者进行其他的流操作。

方法描述示例代码
void write(int b)将指定的字节写入输出流,b 的低 8 位将被写入流中。outputStream.write(255);
void write(byte[] b)将字节数组 b 中的所有字节写入输出流。byte[] data = "Hello".getBytes(); outputStream.write(data);
void write(byte[] b, int off, int len)将字节数组 b 中从偏移量 off 开始的 len 个字节写入输出流。byte[] data = "Hello".getBytes(); outputStream.write(data, 0, data.length);
void flush()刷新输出流并强制写出所有缓冲的数据,确保数据被立即写入目标输出。outputStream.flush();
void close()关闭输出流并释放与该流相关的所有资源。关闭后不能再写入。outputStream.close();

除了 OutputStream 外,还有一些其他的输出流,更多的细节参考下面链接:

下面是一个演示 InputStream 和 OutputStream 用法的例子:

import java.io.*;
 
public class fileStreamTest {
    public static void main(String[] args) {
        try {
            byte bWrite[] = { 11, 21, 3, 40, 5 };
            OutputStream os = new FileOutputStream("test.txt");
            for (int x = 0; x < bWrite.length; x++) {
                os.write(bWrite[x]); // writes the bytes
            }
            os.close();
 
            InputStream is = new FileInputStream("test.txt");
            int size = is.available();
 
            for (int i = 0; i < size; i++) {
                System.out.print((char) is.read() + "  ");
            }
            is.close();
        } catch (IOException e) {
            System.out.print("Exception");
        }
    }
}

上面的程序首先创建文件test.txt,并把给定的数字以二进制形式写进该文件,同时输出到控制台上。

以上代码由于是二进制写入,可能存在乱码,你可以使用以下代码实例来解决乱码问题:

//文件名 :fileStreamTest2.java
import java.io.*;
 
public class fileStreamTest2 {
    public static void main(String[] args) throws IOException {
 
        File f = new File("a.txt");
        FileOutputStream fop = new FileOutputStream(f);
        // 构建FileOutputStream对象,文件不存在会自动新建
 
        OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
        // 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
 
        writer.append("中文输入");
        // 写入到缓冲区
 
        writer.append("\r\n");
        // 换行
 
        writer.append("English");
        // 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
 
        writer.close();
        // 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
 
        fop.close();
        // 关闭输出流,释放系统资源
 
        FileInputStream fip = new FileInputStream(f);
        // 构建FileInputStream对象
 
        InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
        // 构建InputStreamReader对象,编码与写入相同
 
        StringBuffer sb = new StringBuffer();
        while (reader.ready()) {
            sb.append((char) reader.read());
            // 转成char加到StringBuffer对象中
        }
        System.out.println(sb.toString());
        reader.close();
        // 关闭读取流
 
        fip.close();
        // 关闭输入流,释放系统资源
 
    }
}

Java Scanner类

Java异常处理

Java 抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。(顾名思义,就是这个类很抽象,不具体,没有足够的信息,故而称抽象类)抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。

父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。

在 Java 中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口

抽象类

在 Java 语言中使用 abstract class 来定义抽象类。如下实例:略…………

抽象类总结规定

  1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
  2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
  3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
  4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
  5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。

Java 接口

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

  • 一个接口可以有多个方法
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

  • 接口不能用于实例化对象
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现
  • 接口支持多继承。

接口特性

  • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
  • 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。

抽象类和接口的区别

  • 1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
  • 2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  • 3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
  • 4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口

:JDK 1.8 以后,接口里可以有静态方法和方法体了。

:JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。更多内容可参考 Java 8 默认方法

:JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。更多内容可参考 Java 9 私有接口方法


接口的声明

接口的声明语法格式如下:

[可见度] interface 接口名称 [extends 其他的接口名] {
        // 声明变量
        // 抽象方法
}

Interface关键字用来声明一个接口。下面是接口声明的一个简单例子。

/* 文件名 : NameOfInterface.java */
import java.lang.*;
//引入包
 
public interface NameOfInterface
{
   //任何类型 final, static 字段
   //抽象方法
}

接口有以下特性:

  • 接口是隐式抽象的,当声明一个接口的时候,不必使用abstract关键字。
  • 接口中每一个方法也是隐式抽象的,声明时同样不需要abstract关键字。
  • 接口中的方法都是公有的。
/* 文件名 : Animal.java */
interface Animal {
   public void eat();
   public void travel();
}

略………………

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值