【问题标题】:Access Private Members In Private Members Using Java使用 Java 在私有成员中访问私有成员
【发布时间】:2014-12-15 15:50:56
【问题描述】:

所以我想成为一个好朋友,帮助我认识的人学习他们的 Java 类,因为我有编写一些网络应用程序的经验。 (Java 不是我的第一语言)所以他给了我一个他想要帮助的奖金作业。我们似乎确定的其他一切都很好,但是交给我朋友的奖金任务几乎与我对任何编程语言的想法背道而驰。显然,如果你用任何编程语言扩展一个类。 C++、Java、PHP,您只能访问受保护或公开的子类变量。显然,如果您试图访问任何私人的东西或试图打破规则,您需要退后一步。 ...对吗?

显然任务是这样的:您需要修改这个名为“InvoicePrinter”的程序,以便您可以在 HTML 中打印发票,并且您不能修改任何用于 InvoiceFormatter 的 ECXEPT 类

这是程序的总结。

//Address.java
class Address
{
   private String m_name;
   private String m_street;

  Address(String name, String street)
  {
     m_name = name;
     m_street = street;
  }

}

//Invoice.java
class Invoice
{
     private Address m_location;
     private Products m_products;

     Invoice(Address addr)
     {
       m_location = addr;
     }

     public void format()
     {
          //Print data here...
     }
}

//InvoicePrinter
class InvoicePrinter
{
     int main(//...)
     {
        Invoice myInvoice = new Invoice(new Address("My company", "12345 n Street Way"));
        myInvoice.addProduct(new Product("box", 1.20));
        myInvoice.addProduct(new Product("glasses", 5.00));


        //Print Invoice on screen...
        myInvoice.format();


       //Add your invoice printer here here...
     }

}

//InvoiceFormater.java
class InvoiceFormater
{
     private Invoice myInv;

     InvoiceFormater(Invoice invoice)
     {
           myInv = invoice;
     }


    public static void format()
    {
         //Print your HTML formatter here.

    }

}

因此,除非我正在慢慢变成 Java 初学者或其他人,但我看到如何能够从 Invoice 中提取数据的唯一方法是扩展“InvoiceFormatter”并使用 Super,但您仍然需要访问“Invoice” " 数据,例如地址等...那么如何在不更改除 int main 或 InvoiceFormatter 之外的任何代码的情况下执行此操作?

...我承认,这让我有点发疯,只是想它会如何工作,因为这听起来像是《盗梦空间》中的东西或悖论...哈哈

【问题讨论】:

  • 作业似乎自相矛盾;你说InvoicePrinter 是唯一可以修改的类,但是Invoice.formatInvoiceFormatter.format 方法要求你实现它们。
  • 谷歌 java 反射。
  • 你的直觉是正确的,这个任务看起来很荒谬。例如,Address 类在编写时完全没用。唯一明智的方法是修改现有的类。这段代码中还有很多废话,比如int main 不是 Java,(//...) 不是正确的 Java(或 C 或 C++)注释。

标签: java class private


【解决方案1】:

您可以使用“Reflection”获取私有课程信息。反射允许您获取有关类的信息,例如可用的方法和字段。但它也允许你获取字段的值,或者在你发现它们存在后调用方法。

有关反射的更多信息和一些教程,您可以访问 Oracle 的Reflection tutorials

因此,以下问题和接受的答案可能会帮助您解决问题的具体示例:How do I read a private field in Java?

What is reflection and why is it useful? 的接受回答也提供了更多关于反射的信息


请注意,我怀疑这是您老师的预期解决方案...从教学的角度来看,您也可以修改Invoice 似乎更有意义,因为对这些简单的使用反射任务(添加 setter 和 getter)是一个巨大的矫枉过正!

【讨论】:

  • 我同意 Veger 的观点,这有点疯狂,特别是对于 Java 101。我会将这个信息推荐给我的朋友,以包含老师告诉他的内容是真的,或者我的朋友得到他的答案尽管我问了他很多次,但指令混淆了。
【解决方案2】:

根据定义,您不能访问另一个类的私有字段(内部或封闭类除外,但这里不是这种情况)。

让我详细说明一下:Invoice 类中似乎没有字段 m_locationm_products 的访问器,因此您实际上有三个选择:

  • 尝试从format() 的输出中解析回那些字段(这就像作弊)
  • 使用反射 API 在运行时更改私有字段的可访问性(这更像是作弊)
  • 说服分配者,正确的方法是修改Invoice

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 2011-09-28
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多