`getConstructor` 在Java中抛出 `NoSuchMethodException`

huangapple go评论83阅读模式
英文:

getConstructor Throws NoSuchMethodException in Java

问题

我对Java非常新,所以这可能是一个愚蠢的问题,但我正在尝试理解如何通过从现有实例获取类(我想这称为反射)来创建一个类的新实例。

目前我有一个超类和几个子类。

```java
public abstract class SuperClazz {...}

public class SubClazz1 extends SuperClazz {...}

public class SubClazz2 extends SuperClazz {...}

我有一个现有的某个子类的实例(仅声明为超类的成员,因为我还不知道它将属于哪个子类)。我试图获取这个现有实例属于哪个子类,并创建一个相同子类的新实例。

这是我的设置:

private SuperClazz oldSubInstance;
private SuperClazz newSubInstance;

newSubInstance = oldSubInstance.getClass().getConstructor(String.class, char.class, int.class).newInstance("abc", 'e', 6);

这会抛出NoSuchMethodException异常。

我感到困惑,因为我知道SuperClazz有一个构造函数,接受三个参数,一个String,一个char和一个int。我已经查看了这里这里的答案,但发现实施建议的修复方法不起作用,或者他们的问题不适用于我的情况。

我是否完全误解了getConstructor的工作原理?


<details>
<summary>英文:</summary>

I am very new to Java so this may be a dumb question, but I am trying to understand how to create a new instance of a class by getting the class from an existing instance (I think this is called reflection).

Currently I have a super class and several subclasses of it.

public abstract class SuperClazz {...}

public class SubClazz1 extends SuperClazz {...}

public class SubClazz2 extends SuperClazz {...}


I have an existing instance of one of these subclasses (declared only as a member of the super class, as I do not yet know which subclass it will belong to). I am trying to get whichever subclass this existing instance belongs to and make a new instance of that same subclass.

This is my setup:

private SuperClazz oldSubInstance;
private SuperClazz newSubInstance;

newSubInstance = oldSubInstance.getClass().getConstructor(String.class, char.class, int.class).newInstance("abc", 'e', 6);


Which throws NoSuchMethodException.

I am confused because I know SuperClazz has a constructor that takes in three parameters, a String, a char and an int. I have viewed answers [here][1] and [here][2] but have found that implementing the suggested fixes does not work, or that their issues do not apply to my situation.

Am I completely misunderstanding how getConstructor works?


  [1]: https://stackoverflow.com/questions/29195039/java-getconstructor-throws-nosuchmethodexception
  [2]: https://stackoverflow.com/questions/12404963/java-lang-nosuchmethodexception-with-constructor-newinstance

</details>


# 答案1
**得分**: 1

你需要确保子类中存在包含所有参数的构造函数。

以下示例创建一个`newSubInstance`:
```java
// 使用 Lombok 注解简化代码
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
abstract class SuperClazz {
    private String str;
    private char chr;
    private int x;

    // Lombok 提供的获取器/设置器/默认构造函数和全参构造函数
}

class SubClazz1 extends SuperClazz {
    public SubClazz1(String str, char c, int i) { // 在子类中提供构造函数
        super(str, c, i);
    }
}

// 测试
SuperClazz oldSubInstance = new SubClazz1("def", 'g', 10);
SuperClazz newSubInstance;

newSubInstance = oldSubInstance.getClass()
                               .getConstructor(String.class, char.class, int.class)
                               .newInstance("abc", 'e', 6);

System.out.println(newSubInstance);

输出(在基类级别重写了 toString):

SuperClazz(str=abc, chr=e, x=6)
英文:

You need to make sure that the all-args constructor exists in the children class(es).

The following example creates a newSubInstance:

// using Lombok annotations for brevity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
abstract class SuperClazz {
    private String str;
    private char chr;
    private int x;

    // getters/setters/default and all-args constructors provided by Lombok
}


class SubClazz1 extends SuperClazz {
    public SubClazz1(String str, char c, int i) { // providing constructor in the child class
        super(str, c, i);
    }
}

// test
SuperClazz oldSubInstance = new SubClazz1(&quot;def&quot;, &#39;g&#39;, 10);
SuperClazz newSubInstance;

newSubInstance = oldSubInstance.getClass()
                               .getConstructor(String.class, char.class, int.class)
                               .newInstance(&quot;abc&quot;, &#39;e&#39;, 6);

System.out.println(newSubInstance);

output (toString overridden at the base class level):

SuperClazz(str=abc, chr=e, x=6)

huangapple
  • 本文由 发表于 2020年10月15日 20:44:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/64371880.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定