1401 字
7 分钟
JAVA速成

Java类#

Java类和cpp类的区别:

  • java几乎所有的代码都在类里面,而cpp一般包含.h和.cpp两个文件,.h文件中定义类,.cpp文件中实现类
  • java类中的所有方法默认是非静态的,所有非static修饰的都可以重写,重写的时候用@Override注解,cpp类中的方法默认是静态的,需要virtual关键字修饰才可以重写

Java类的继承#

Java类的继承使用关键字 extends。Java是单继承的,一个类只能继承一个父类。

class <子类名> extends <父类名> {
// 子类的类体
}

在子类的类体中:

  • 子类的构造函数必须调用父类的构造函数。可以使用super(参数)来调用父类的构造函数。super()必须是子类构造函数的第一条语句。

    class 父类 {
    父类(参数) {
    // 父类的构造函数体
    }
    }
    class 子类 extends 父类 {
    子类(参数) {
    super(参数); // 调用父类的构造函数,这个参数必须和父类的构造函数参数匹配
    // 子类的构造函数体
    }
    }
  • super关键字用于访问父类的成员变量(非private变量)和方法。可以使用super.成员变量访问父类的成员变量,使用super.方法名()调用父类的方法。可以对父类非static方法既重写又调用父类的方法。

  • 子类可以重写父类的方法。重写的方法必须与父类的方法具有相同的名称、参数列表和返回类型。重写的方法可以使用@Override注解来标识。

Java创建对象#

普通对象#

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

  • 声明:声明一个对象,包括对象名称和对象类型
  • 实例化:使用关键字 new 来创建一个对象。
  • 初始化:使用 new 创建对象时,会调用构造函数初始化对象。
类名 对象名 = new 类名(参数);
数据类型[] 数组名 = new 数据类型[数组大小];

匿名对象#

匿名对象是没有名称的对象。匿名对象通常用在只需要使用一次的场景中。

new 类名(参数).方法名();
// 例如
player.addEffect(new MobEffectInstance(LastBreath.DYING_MOB_EFFECT, Integer.MAX_VALUE, 0, false, false));

这个例子中,new MobEffectInstance(...) 创建了一个匿名对象,并将其作为参数传递给 addEffect 方法。给玩家添加了一个效果。

Java中的注解@#

在 Java 中,注解是一种表示附加在类、接口和方法上的额外信息的方式。Java 编译器和 JVM 使用提供的信息和注解。注释以@ 符号开头。

Java中的泛型#

在普通的函数参数列表中,形参类型是在函数定义中声明的(比如cppvoid func(int 形参)),只能传入符合该类型的参数作为实参。而在泛型函数中,形参类型是一个占位符(比如java<T> void func(T 形参)),在函数调用的时候传入实参时,实参的类型会替换掉占位符,从而确定形参的类型。

泛型的本质是为了将类型参数化, 也就是说在泛型使用过程中,数据类型被设置为一个参数,在使用时再从外部传入一个数据类型;而一旦传入了具体的数据类型后,传入变量(实参)的数据类型如果不匹配,编译器就会直接报错。

这种参数化类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

泛型类#

泛型类就是在类定义时使用一个或多个类型参数(比如下面的<T><K>),根据这个<T>的值让这个类可以操作不同类型的数据,而不需要为每种类型写一份代码。

class 类名<T, K> {
T 成员变量1;
K 成员变量2;
类名(T 参数1, K 参数2) {
成员变量1 = 参数1;
成员变量2 = 参数2;
}
T 方法名1() {
return 成员变量1;
}
K 方法名2() {
return 成员变量2;
}
}

泛型类的使用方式:

类名<具体类型1, 具体类型2> 对象名 = new 类名<>(参数1, 参数2);
// 例如
public static final DeferredRegister<MobEffect> MOB_EFFECTS = DeferredRegister.create(Registries.MOB_EFFECT, MODID);

在这个例子中,DeferredRegister<> 是一个泛型类,MobEffect 是传入的具体类型。

注意事项
  • 泛型类型不能是基本类型(如 int),要用包装类(如 Integer)

  • 泛型信息在运行时会被“擦除”(类型擦除),所以不能用 T.class

  • 不能创建泛型数组:new T[10] 是非法的

  • 不能实例化泛型类型:new T() 是非法的

  • 不能声明静态成员为泛型类型:static T 静态成员变量 是非法的

  • 不能在静态方法中使用泛型类型:static void 方法名() 是非法的

泛型方法#

泛型方法就是在方法定义时使用一个或多个类型参数(比如下面的<T>),根据这个<T>的值让这个方法可以操作不同类型的数据,而不需要为每种类型写一份代码。

<T> 返回类型 方法名(T 参数) {
// 方法体
}

泛型方法的使用方式:

方法名(具体类型 参数);
// 例如
public static <T> void register(DeferredRegister<T> register, String name, Supplier<?extends T> sup) {
register.register(name, sup);
}

在这个例子中,<T> 是一个类型参数,DeferredRegister<T> 使用了这个类型参数。

JAVA速成
https://biscuit0613.github.io/posts/programming/java_speedrun/
作者
Biscuit
发布于
2025-09-14
许可协议
CC BY-NC-SA 4.0