在调用超级构造函数之前检查变量的有效性

时间:2017-02-11 18:39:07

标签: java class constructor extends super

所以我编写了一些代码,这些代码涉及扩展我之前编写过的类,其中的文件是使用构造函数创建和命名的,该构造函数的名称和类型为long。在那个原始类中,我在构造函数中验证了输入的文件名包含一个"。"字符但不需要对文件进行特定扩展。对于我正在编写的这个新类,我要求名称的扩展名是" .mp3"。但是,我的编译器不喜欢超级构造函数之前的验证。

这是我目前的代码:

public class Song extends DigitalMedia{

private String artist;
private String album;
private String name;
private long size;

public Song(String aName, long aSize, String aArtist, String aAlbum){
    super(aName, aSize);
    setArtist(aArtist);
    setAlbum(aAlbum);
}

有没有办法验证" aName"包含" .mp3"在我创建该构造函数之前?

4 个答案:

答案 0 :(得分:3)

我不能说它是否是设计程序的最佳方式,但您可以在super个参数中调用验证器方法:

public Song(String aName, long aSize, String aArtist, String aAlbum){
    super(validateName(aName), aSize);
    setArtist(aArtist);
    setAlbum(aAlbum);
}

private static String validateName(String name) {
    if (whatever) {
        throw new Whatever();
    }
    return name;
}

答案 1 :(得分:2)

到达constructor的代码执行意味着该对象处于活动状态,现在可以初始化其states(字段)。

A.java的对象也可以被称为A.java的超类对象。在类A.java初始化状态之前,对象继承超类的属性和特性是有道理的。在超类进行初始化之后,类A.java有机会进行初始化。

如果超类中存在无参数构造函数,则隐式调用超类的构造函数,否则需要显式调用超类的任何一个参数化构造函数。

如果条件在constructor失败,您希望做什么?您可以选择抛出异常,但仍然创建了对象,您可以通过覆盖finalize()方法并检查this对象来验证它。您可能希望通过调用System.gc()来影响垃圾回收器,以便更快地到达finalize()方法执行代码。

建议的解决方案 您应该在调用构造函数之前验证构造函数的参数。如果要将其封装在类中,则可以选择添加非私有静态方法(您可能希望将其命名为getInstance())创建并返回类Song的对象。在这种情况下,您可以将构造函数设置为私有。请注意,这将使您的类不可扩展,它只是一个设计选择。

答案 2 :(得分:1)

另一种解决方案是通过内置类型检查来强制执行规则。

您可以创建MediaFormat

interface MediaFormat { }

实现MusicFormat的{​​{1}},允许您指定支持的音乐格式:

MediaFormat

enum MusicFormat implements MediaFormat { MP3("mp3"); private final String format; MusicFormat(String format) { this.format = format; } @Override public String toString() { return format; } } 可以由DigitalMedia

组成
MediaFormat

class DigitalMedia { private final MediaFormat format; private final String name; public DigitalMedia(String name, MediaFormat format) { this.name = name; this.format = format; } } 可以接受Song

MusicFormat

这将强制用户使用class Song { public Song(String name, MusicFormat format) { super(name, format); } } 中指定的任何内容,避免所有那些讨厌的检查。然后,您可以公开返回MusicFormat

String方法

答案 3 :(得分:0)

从继承角度来看,一个子类不应该比它的超级类更具限制性。

但是如果你想让子类的实例化受到更多限制,你可以创建构造函数[1,3,5] 并提供一个首先进行验证的工厂方法。

private

您可以使用封装来强制执行不变量,而不是限制类型本身。