使用“Object”关键字在Java中创建对象

时间:2016-04-15 17:21:20

标签: java class object

我刚刚开始学习java,我有两个基本问题。 我的main()看起来像这样:

public class Main {
public static void main(String[] args) {
    Storage<BankAccount> aStorage = new Storage<BankAccount>(); 
    Storage<String> sStorage = new Storage<String>();

    Class baCls = BankAccount.class;
    try {
    Object myAccount = baCls.newInstance();
    aStorage.setValue( myAccount );
    myAccount.deposit( 15 );
    }
    catch ( InstantiationException e ) {
    }
    catch ( IllegalAccessException e ) {
    }
}}

为什么我会收到这些错误:

  • 对象类型
  • 未定义方法deposit(int)
  • 存储类型中的方法setValue(BankAccount)不适用于参数(Object)。

之后我试图替换:

Object myAccount = baCls.newInstance();

BankAccount myAccount = baCls.newInstance();

但后来我收到了这个错误:

  • 类型不匹配:无法从Object转换为BankAccount

我知道正确的方法是:

BankAccount myAccount = (BankAccount) baCls.newInstance();

但我不确定我明白为什么...... 我尝试从各种来源阅读它,所以我有一些理论,但我仍然无法正确地理解这一点。 有人可以帮我理解吗?

P.S。 很抱歉发布了这样一个基本问题。

2 个答案:

答案 0 :(得分:9)

执行BankAccount myAccount = baCls.newInstance()调用反射来创建新对象。 Class是通用的,但您尚未指定泛型类型。如果你做Class<BankAccount> baCls = BankAccount.class那么你就不需要施放。

Java是强类型的。通过将对象声明为object,您对语言说这个对象只是一个对象:就是它只有在所有对象上找到的方法和字段,仅此而已。

通过指定类型,您可以告诉Java您可以访问哪些方法和字段,这就是为什么当您编写BankAccount myAccount时,它允许您在其上调用函数。

但是baCls.newInstance()创建了一个baCls类的新实例。它不知道它正在创建什么类型的类,因为它是Class类上的一个方法(令人困惑)本身,所以你必须告诉Java你希望它通过转换返回什么类:BankAccount myAccount = (BankAccount) baCls.newInstance();

然而,更大的问题是您首先使用newInstance的原因。是否可以这样做:

BankAccount myAccount = new BankAccount();

初学者的反思有点先进。

答案 1 :(得分:2)

因为您已经通过Object界面对其进行了定义,而Object界面并不了解您的对象特定方法,例如deposit()。

Object myAccount = baCls.newInstance();

应该......

BankAccount myAccount = (BankAccount)(baCls.newInstance());

或者只是......

BankAccount myAccount = new BankAccount();

然后,您可以在BankAccount定义的合同中调用存款,假设baCls确实是BankAccount。如果您不确定其类型,可以事先使用instanceof BankAccount进行检查。

进一步解释......

如果我定义了一个OperatingSystem类,那么我将该类子类化为UnixOperatingSystemWindowsOperatingSystem。现在,显然有一些常见的东西,但也特定于每台计算机。但如果我这样做......

OperatingSystem os = new WindowsOperatingSystem();

然后,我正在创建一个WindowsOperatingSystem,但只允许调用常见的OperatingSystem方法,因为它通过方法签名契约在超类中定义了什么。因此,我可以调用shutdown()方法(因为任何操作系统都应该能够关闭),而不是runBatchFile("test.bat")方法。我需要将它明确声明为WindowsOperatingSystem才能调用该特定方法。