【问题标题】:(Java) Static member accessed via instance reference with enumerators(Java) 使用枚举器通过实例引用访问的静态成员
【发布时间】:2021-08-16 22:27:11
【问题描述】:

我刚开始学习 Java。 IntelliJ 在第 4 行给我一个警告“通过实例引用访问的静态成员”。这很糟糕,我应该以某种方式修复它,还是应该忽略它?

这是我的代码:

public class MainClass {
    public static void main(String[] args) {
        Dog randomDog = new Dog();
        Dog myDog = new Dog(4, "Charlie", new Dog().breed.Labrador);
        System.out.println("Random dog's name is: " + randomDog.name + ", it's age is: " + randomDog.age + " and it's breed is: " + randomDog.breed);
        System.out.println("My dog's name is: " + myDog.name + ", it's age is: " + myDog.age + " and it's breed is: " + myDog.breed);
    }
}

还有 Dog 类:

public class Dog {
    int age;
    String name;
    enum breed { Poodle, Shepherd, Labrador }
    breed breed;

    Dog(int age, String name, breed breed) {
        this.age = age;
        this.name = name;
        this.breed = breed;
    }
    Dog() {
        this.age = 0;
        this.name = "Rex";
        this.breed = breed.Labrador;
    }
}

【问题讨论】:

  • 修复问题:Dog.breed.Labrador。顺便说一句,不要将字段称为与类型相同的字段,这只会令人困惑。调用枚举Breed 和字段breed。按照惯例,枚举值是大写的。
  • @AndyTurner 实际上需要重命名枚举,因为Dog.breed.Labrador 失败。看起来该属性会影响该类中的枚举。
  • 问:不好吗?答:这只是一个“警告”——一切仍将按预期工作。一个更大的问题是“枚举品种”和实例变量“品种”之间的命名冲突。您应该考虑为所有成员设置明确的可见性(即“公共”、“私人”或“受保护”)。
  • @Tom 很有趣,我想知道您如何在不重命名的情况下从课堂外引用breed。也许这是Java无法处理的另一种有趣的情况,例如stackoverflow.com/questions/50633759/…。我想这取决于上下文,因为Dog.breed breed = null; 会起作用,因为它只能是一个类型。
  • @AndyTurner 我想如果不解决歧义就没有办法做到这一点。我还发现了一个同样问题的问题:Java Enums and Fields with same name

标签: java variables enums static enumerator


【解决方案1】:

一个问题(导致其他问题)是您隐藏了 type breed,因为在同一范围内还有一个同名的字段

这是一个非常罕见的问题,因为 Java 的命名约定通常会防止这种冲突:类型(类、接口、枚举、注释)通常用 CamelCase 编写,而字段名称以小写字母开头(fieldName)。虽然这在技术上不是编译器强制执行的“规则”,但遵循此规则会使您的代码对其他人更具可读性,并且还避免了隐藏类型的后续问题。还要注意常量字段。

我还做了两个很好的改动,但与您的问题并不真正相关:

  • 常量值(即大多数static final 字段和枚举常量)使用ALL_UPPER 大小写,所以我也更改了您的Breed
  • 我已将嵌套类型定义移至Dog 类的顶部,以免将其隐藏在所有实例字段中。这只是为了让那些在逻辑上属于一起的事物彼此靠近。
public class Dog {
    enum Breed { POODLE, SHEPHERD, LABRADOR }

    int age;
    String name;
    Breed breed;

    Dog(int age, String name, Breed breed) {
        this.age = age;
        this.name = name;
        this.breed = breed;
    }
    Dog() {
        this.age = 0;
        this.name = "Rex";
        this.breed = Breed.LABRADOR;
    }
}

在主类中更改所有这些名称并用 Dog.Breed 替换未定义的 new Dow().breed 会生成以下工作代码:

public class MainClass {
    public static void main(String[] args) {
        Dog randomDog = new Dog();
        Dog myDog = new Dog(4, "Charlie", Dog.Breed.LABRADOR);
        System.out.println("Random dog's name is: " + randomDog.name + ", it's age is: " + randomDog.age + " and it's breed is: " + randomDog.breed);
        System.out.println("My dog's name is: " + myDog.name + ", it's age is: " + myDog.age + " and it's breed is: " + myDog.breed);
    }
}

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 2021-08-19
    • 2021-11-26
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    相关资源
    最近更新 更多