【问题标题】:In Java, can I consolidate two similar functions where uses JspWriter and the other PrintWriter?在 Java 中,我可以合并两个使用 JspWriter 和另一个 PrintWriter 的类似功能吗?
【发布时间】:2010-10-03 12:42:47
【问题描述】:

我有以下类,正如您将看到的那样,它有一个相当多余的 formatNameAndAddress 方法:

package hu.flux.helper;
import java.io.PrintWriter;

import javax.servlet.jsp.JspWriter;

// A holder for formatting data 
public class NameAndAddress 
{
 public String firstName;
 public String middleName;
 public String lastName;
 public String address1;
 public String address2;
 public String city;
 public String state;
 public String zip;

 // Print out the name and address.
 public void formatNameAndAddress(JspWriter out)
  throws java.io.IOException
  {
   out.println("<PRE>");
    out.print(firstName);

    // Print the middle name only if it contains data.
    if ((middleName != null) && (middleName.length() > 0)) 
     {out.print(" " + middleName);}

    out.println(" " + lastName);

    out.println(" " + address1);

    if ((address2 != null) && (address2.length() > 0))
     out.println(" " + address2);

    out.println(city + ", " + state + " " + zip);
   out.println("</PRE>");
  }

 public void formatName(PrintWriter out) 
 {
  out.println("<PRE>");
  out.print(firstName);

  // Print the middle name only if it contains data.
  if ((middleName != null) && (middleName.length() > 0)) 
   {out.print(" " + middleName);}

  out.println(" " + lastName);

  out.println(" " + address1);

  if ((address2 != null) && (address2.length() > 0))
   out.println(" " + address2);

  out.println(city + ", " + state + " " + zip);
  out.println("</PRE>");
 }
}

我想重写该类以使用通用方法,例如:

     // Print out the name and address.
 private void genericFormatNameAndAddress(Object out)
 {
  out.println("<PRE>");
   out.print(firstName);

   // Print the middle name only if it contains data.
   if ((middleName != null) && (middleName.length() > 0)) 
    {out.print(" " + middleName);}

   out.println(" " + lastName);

   out.println(" " + address1);

   if ((address2 != null) && (address2.length() > 0))
    out.println(" " + address2);

   out.println(city + ", " + state + " " + zip);
  out.println("</PRE>");
 }

但是,我不能这样做,因为 Object 没有 print() 和 println() 方法。如果我将输出转换为 JspWriter 或 PrintWriter,有时我会以错误的方式转换它。

我想我需要做的是以某种方式将对象类型作为变量传递,然后使用该变量来确定如何转换。这可能吗?如果是这样,怎么做?如果没有,什么是好的解决方案?

【问题讨论】:

    标签: java jsp polymorphism casting printwriter


    【解决方案1】:

    这可能会起作用:

    public void formatNameAndAddress(JspWriter out) throws java.io.IOException {
        formatNameAndAddress(new PrintWriter(out));
    }
    

    【讨论】:

    • 知道我可以将 JspWriter 转换为 PrintWriter,因此我尝试将我的修订更进一步(也结合了史蒂夫的智慧)......但是,现在我有一个新问题,我在 @987654321 询问@
    • @Brian,不,你不能转换,JspWriter 不是PrintWriter 的子类。
    • 那么,上述方法虽然有效地进行了强制转换,但实际上并不是强制转换(至少就 Java 而言)?
    • 它不是强制转换,而是创建一个新对象,将调用委托给原始对象。
    • 我明白了......为澄清干杯。
    【解决方案2】:

    您有点用这些方法混淆了两个不同的任务,并打破了专门化的 OO 原则。也就是说,您有负责格式化两种类型的字符串之一的方法......并负责将它们发送到两种类型的输出目标之一。

    更好的方法可能是使您的方法更专业。也就是说,让他们只负责构建“名称”字符串或“名称和地址”字符串......并返回 String 作为方法的返回类型。

    在您调用这些方法的代码中,您显然已经有一个JspWriterPrintWriter 对象...因为现在您将它作为方法参数传递。因此,简单地将该对象留在代码中的位置,并让它打印出由您的专用输出不可知方法返回的String 会更干净。

    【讨论】:

    • 实际上,它们最终具有相同的输出目标。一种方法是从 servlet 调用的,另一种方法是从 JSP 页面调用的,据我所知,在提供服务之前实际上已将其更改为 servlet。但是,我想我明白你的建议。为响应干杯!
    【解决方案3】:

    如果您想将对象转换为正确的 Writer,您可以尝试以下操作:

    private void genericFormatNameAndAddress(Object out){
        if (obj instanceof Printwriter){
            //cast to printwriter
        } else {
            //cast to JspWriter
        }
    

    Barkers 解决方案似乎更适合,因为 Printwriter 可以由 JspWriter 构建。

    【讨论】:

    • 为响应干杯,但我认为这不会真正做到我想要的,因为如果我在每个强制转换实例之前检查它只会使代码更长更复杂并且不会'如果只将其拆分并再次单独处理,则将“out”传递给此函数并没有太大优势。
    【解决方案4】:

    JspWriterPrintWriter 都是 java.io.Writer 的子类。由于您不使用任何特定于两者的任何功能,您可以将该方法声明为采用java.io.Writer

    public void formatNameAndAddress(Writer out) throws java.io.IOException
    {
        [...]
    

    然后根据需要传递JspWriterPrintWriter

    编辑:这在不实际修改代码的情况下是行不通的,因为正如其他人指出的那样,Writer 没有 printprintln 方法,而 JspWriterPrintWriter 都提供它们。

    【讨论】:

    • println 不在 Writer 中,它在 JspWriterPrintWriter 中,但它仍然特定于每个类。
    • 刚试过这个,但这个签名似乎没有捕捉到JspWriter。我一直在探索类似的方法,并将这个迄今为止的不幸事件产生的问题发布到stackoverflow.com/questions/3850079/…
    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多