相关疑难解决方法(0)

有没有理由在生成.equals()时更喜欢getClass()而不是instanceof?

我正在使用Eclipse生成.equals().hashCode(),并且有一个选项标记为"使用'instanceof'来比较类型".默认情况下,此选项可以取消选中并用于.getClass()比较类型.有什么理由我应该喜欢.getClass()instanceof

不使用instanceof:

if (obj == null)
  return false;
if (getClass() != obj.getClass())
  return false;
Run Code Online (Sandbox Code Playgroud)

使用instanceof:

if (obj == null)
  return false;
if (!(obj instanceof MyClass))
  return false;
Run Code Online (Sandbox Code Playgroud)

我通常检查instanceof选项,然后进入并删除" if (obj == null)"检查.(这是多余的,因为空对象总是会失败instanceof.)有什么理由不好吗?

java eclipse equals instanceof

168
推荐指数
8
解决办法
12万
查看次数

在Java中避免使用instanceof

具有一系列"instanceof"操作被认为是"代码味道".标准答案是"使用多态".在这种情况下我该怎么做?

基类有许多子类; 没有一个在我的控制之下.类似的情况是Java类Integer,Double,BigDecimal等.

if (obj instanceof Integer) {NumberStuff.handle((Integer)obj);}
else if (obj instanceof BigDecimal) {BigDecimalStuff.handle((BigDecimal)obj);}
else if (obj instanceof Double) {DoubleStuff.handle((Double)obj);}
Run Code Online (Sandbox Code Playgroud)

我确实可以控制NumberStuff等等.

我不想在几行代码中使用多行代码.(有时我将一个HashMap映射到一个IntegerStuff的实例,将BigDecimal.class映射到一个BigDecimalStuff的实例等等.但是今天我想要一些更简单的东西.)

我想要像这样简单的东西:

public static handle(Integer num) { ... }
public static handle(BigDecimal num) { ... }
Run Code Online (Sandbox Code Playgroud)

但是Java不会那样工作.

我想在格式化时使用静态方法.我正在格式化的东西是复合的,其中Thing1可以包含一个数组Thing2s和Thing2可以包含一个Thing1s数组.当我实现这样的格式化程序时,我遇到了问题:

class Thing1Formatter {
  private static Thing2Formatter thing2Formatter = new Thing2Formatter();
  public format(Thing thing) {
      thing2Formatter.format(thing.innerThing2);
  }
}
class Thing2Formatter {
  private static Thing1Formatter thing1Formatter = new Thing1Formatter();
  public format(Thing2 thing) {
      thing1Formatter.format(thing.innerThing1);
  }
}
Run Code Online (Sandbox Code Playgroud)

是的,我知道HashMap和更多代码也可以修复它.但相比之下,"instanceof"似乎更具可读性和可维护性.有什么简单但不臭吗?

注释已添加5/10/2010:

事实证明,将来可能会添加新的子类,而我现有的代码必须优雅地处理它们.在这种情况下,类上的HashMap不起作用,因为找不到类.一系列if语句,从最具体的开始到以最一般的结尾,可能是最好的:

if (obj instanceof SubClass1) …
Run Code Online (Sandbox Code Playgroud)

java reflection polymorphism instanceof chain-of-responsibility

96
推荐指数
7
解决办法
7万
查看次数

在java中切换类型

在开始之前,我知道这个问题有很多答案可以提出替代方法.我正在寻求这种特殊方法的帮助,以确定是否可行,如果不可能,可能会有类似的方法.

我有一个方法,它接受一个超类并根据传递的对象的类型调用一个方法.例如:

public void handle(Object o){
  if (o instanceof A)
    handleA((A)o);
  else if (o instanceof B)
    handleB((B)o);
  else if (o instanceof C)
    handleC((C)o);
  else 
    handleUnknown(o);
Run Code Online (Sandbox Code Playgroud)

我不能修改子类型来覆盖一个handle()方法,正如这个答案所暗示的那样,因为我不拥有这些类.所以这个instanceof方法就是我所拥有的.

我想用一个switch声明代替if/else,只是因为它更整洁.我知道你只能打开基元和字符串,所以我要切换类名:

switch(o.getClass().getCanonicalName()){
case "my.package.A":
  handleA((A)o);
  break;
case "my.package.B":
  handleB((B)o);
  break;
case "my.package.C":
  handleC((C)o);
  break;
default:
  handleUnknown(o);
  break;
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是规范名称非常长(如12个子包),我不能调用ClassName.class.getCanonicalName()case语句,因为Java不允许这样做.所以我的下一个解决方案是Enum.这是我遇到问题的地方.

我希望我的代码看起来像这样:

public enum Classes {
  A (A.getCanonicalName()),
  B (B.getCanonicalName()),
  C (C.getCanonicalName());
}

switch (o.getClass().getCanonicalName()){
case Classes.A:
  handleA((A)o);
  break;
case Classes.B:
  handleB((B)o);
  break;
case …
Run Code Online (Sandbox Code Playgroud)

java enums types instanceof switch-statement

27
推荐指数
3
解决办法
5万
查看次数

HashMap与Switch语句性能

HashMap本质上具有O(1)性能,而开关状态可以具有O(1)或O(log(n)),具体取决于编译器是使用tableswitch还是查找开关.

可以理解的是,如果switch语句是这样编写的,

switch (int) {
    case 1:
    case 2:
    case 3:
    case 4:
    default:
}
Run Code Online (Sandbox Code Playgroud)

那么它将使用一个tableswitch,并且显然比标准的HashMap具有性能优势.但是如果switch语句稀疏怎么办?这将是我要比较的两个例子:

HashMap<Integer, String> example = new HashMap<Integer, String>() {{
        put(1, "a");
        put(10, "b");
        put(100, "c");
        put(1000, "d");
}};
Run Code Online (Sandbox Code Playgroud)

.

switch (int) {
    case 1:
        return "a";
    case 10:
        return "b";
    case 100:
        return "c";
    case 1000:
        return "d";
    default:
        return null;
}
Run Code Online (Sandbox Code Playgroud)

什么会提供更多的吞吐量,lookupswitch或HashMap?HashMap的开销是否能够尽早为lookupswitch提供优势,但随着案例/条目数量的增加最终逐渐减少?

编辑:我尝试了一些使用JMH的基准测试,这里是我的结果和使用的代码.https://gist.github.com/mooman219/bebbdc047889c7cfe612 正如你们提到的,lookupswitch语句的表现优于HashTable.我仍然想知道为什么.

java hashmap switch-statement

23
推荐指数
2
解决办法
2万
查看次数

Java访问者模式而不是instanceof开关

在这个问题中,据说我可以使用访客模式而不是一堆instanceofs.Jmg说:"如果你不能自由改变A,B和C,你可以应用访客模式来实现同样的目标."

据我所知,我仍然需要为A,B和C支持访问者(accept()例如,有一个方法).

我的问题是我完全没有可能改变A,B和C.我只是从外国图书馆获得Car对象并且必须调用wash()特定于卡车,赛车和公共汽车的方法.

我想我还需要一个if-else-ifinstanceofs 的结构.我对吗?

java visitor

10
推荐指数
1
解决办法
7130
查看次数

创建许多对象类型/类只是为了使用instanceof

我想知道我是否正在创建/分解对象类型为无意义的类,以及是否有更好的方法来做到这一点.

假设我有以下类( - > 扩展更高级的类):

Vehicle class - takes care of movement and a default speed
-->Car class - adds passengers
-->-->ElectricCar class - a default constructor
-->-->GasolineCar class - a default constructor
-->-->HybridCar class - a default constructor
-->Motorcycle class - a default constructor
-->Bike class - a default constructor, overrides speed
-->Segway class - a default constructor, overrides speed
Run Code Online (Sandbox Code Playgroud)

如您所见,它们大多是默认构造函数.所以我只是创建它们以防我需要使用instanceof条件语句.我的大多数代码最终都在Vehicle类中,因为我试图避免在每个类中重复相同的代码.另外,我应该让汽车抽象,对吗?我从不创建一个Vehicle对象.

这样可以或有更好的方法吗?

java oop instanceof

5
推荐指数
1
解决办法
172
查看次数

如何使switch语句更面向对象?

我试图重构一个这样的switch语句:

private void Validate(DataTypeEnum dataType, string value, ...)
{
    switch(dataType)
    {
        case DataTypeEnum.Number:
            var typedValue = int.Parse(value);
            //Validation of typedValue
            break;
        case DataTypeEnum.Decimal:
            var typedValue = Decimal.Parse(value);
            //Validation of typedValue
            break;
        case DataTypeEnum.DateTime:
            var typedValue = DateTime.Parse(value);
            //Validation of typedValue
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想摆脱switch语句,并以某种方式用更面向对象的构造替换它.有什么建议?

我的理想是这样的:

private void Validate(DataTypeEnum dataType, string value, ...)
{
    Validate(value);
}
private void (Decimal value)
{
    //Validate
}
private void (DateTime value)
{
    //Validate
}
Run Code Online (Sandbox Code Playgroud)

有没有优雅的方法来解决这个问题?

.net c#

4
推荐指数
2
解决办法
387
查看次数

可以使用switch语句来确定对象的类吗?

在搜索了SO和网络之后,我还没有在Java中找到答案.这很简单.

我有抽象类ParentClass.类X和类Y都继承自ParentClass.我也有类DataInputDialog extends JDialog,这是为了提供一个用户界面,用于将数据输入到类X和类Y实例中.DataInputDialog类如下所示:

public class DataInputDialog extends JDialog {

    public DataInputDialog(ParentClass xOrY) {
        //calls super constructor, makes basic components such as
        //  buttons and panels that are used in either X or Y data entry

    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想要一个switch声明来确定ParentClass传递给哪种类型的声明DataInputDialog.但是,我不知道如何实现这一目标.我试过了:

switch (xOrY.getClass().getTypeName()) {
    case X.class.getTypeName();
}
Run Code Online (Sandbox Code Playgroud)

还有其他一些变体,但它总是在case语句中出现一个错误:它必须是一个常量String,或者它不能转换为整数.

如何获取此switch语句以确定是否xOrYX或的实例Y

java class switch-statement

1
推荐指数
1
解决办法
6171
查看次数