【问题标题】:Creating class name generator in java在java中创建类名生成器
【发布时间】:2021-12-12 09:23:19
【问题描述】:

我在 java 中自动命名变量时遇到了很多问题。

有问题的问题:

我正在做一个课堂点(不同于java.awt.Point)。它有一个属性this.name。从testPoint.java 我只需创建一个Point 并打印它的名称。

要创建一个点,我有两个链接的构造函数:

public Point() {
        this("AutoName");
    }

public Point(String name) {
        this.name = name;
    }

如果在testPoint.java 中给出了名称,则将根据该名称命名该点。如果没有给出名称,该点将被命名为AutoName

我想要的是,如果没有给出名称,第一个没有命名的 Point 将获得 AutoName1 作为名称,第二个 AutoName2 等等。

有没有办法在不引入新课程的情况下做到这一点?如果我可以像在 C 和 Python 中一样在 java 中创建全局变量会很容易,但我认为这不尊重封装原则......

【问题讨论】:

    标签: java constructor encapsulation naming


    【解决方案1】:

    在类中使用static int 来保存实例化的数量

    
    class Point {
        static int creationCount = 1;
        String name;
    
        public Point() {
            this("AutoName" + (creationCount++));
        }
    
        public Point(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Point{name='" + name + "'}";
        }
    }
    
    System.out.println(new Point());       // Point{name='AutoName1'}
    System.out.println(new Point("abc"));  // Point{name='abc'}
    System.out.println(new Point());       // Point{name='AutoName2'}
    System.out.println(new Point("bcd"));  // Point{name='bcd'}
    

    【讨论】:

      【解决方案2】:

      accepted solution 适用于单线程应用程序,例如当有一个循环创建点时。

      但是,如果有多个线程创建 Point 类的实例,creationCount 的值可能会针对不同的点重复,并且将计数器变量定义为 static volatile 并不能保证其值的唯一性,因为前后增量不是原子操作。

      因此,在一般情况下,为上述目的使用更多线程安全的AtomicInteger 可能会更好:

      import java.util.concurrent.atomic.AtomicInteger;
      
      class Point {
          static AtomicInteger creationCount = new AtomicInteger(1);
          String name;
      
          public Point() {
              this("AutoName" + creationCount.getAndIncrement());
          }
      
          public Point(String name) {
              this.name = name;
          }
      
          @Override
          public String toString() {
              return "Point{name='" + name + "'}";
          }
      }
      

      【讨论】:

      • 本想自己指出这一点,但你打败了我。全局可变状态已经很糟糕了,不能让它成为非线程安全的。
      【解决方案3】:

      您可以使用静态变量来做到这一点:

      class Point {
        static int counter = 1;
        String name;
        
        public Point() {
          this("AutoName" + counter);
          counter++;
        }
      
        public Point(String name) {
          this.name = name
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-12-18
        • 2014-03-12
        • 2012-11-19
        • 2017-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多