如何将instanceof类型分配给变量?

发布于 2025-01-13 03:26:35 字数 644 浏览 0 评论 0原文

我想知道是否可能以及如何将 type 引用存储到变量中,以便稍后可以与 instanceof 运算符一起使用。

例如,

Book book = new Book("My Favourite Book", "Some Author");

BookType bookType = Book;

if(book instanceof bookType){
    // Do something
}

不必对其进行硬编码:

Book book = new Book("My Favourite Book", "Some Author");

if(book instanceof Book){
    // Do something
}

是否可以使用反射从 Book.class 获取 Book type

我没有找到太多关于这个话题的信息。

请注意,这与使用不同,

Book.class.isInstance(book);
Object value = Book.class.cast(book);

因为我会丢失 Book 类的所有方法。

I am wondering if it is possible and how to store a type reference into a variable so that it can be later used with the instanceof operator.

For example

Book book = new Book("My Favourite Book", "Some Author");

BookType bookType = Book;

if(book instanceof bookType){
    // Do something
}

Instead of having to hard code it:

Book book = new Book("My Favourite Book", "Some Author");

if(book instanceof Book){
    // Do something
}

Is it possible to get the Book type from Book.class maybe using reflection?

I did not found much about this topic.

Note that this is not the same as using

Book.class.isInstance(book);
Object value = Book.class.cast(book);

because I would lose all the methods of the Book class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

×纯※雪 2025-01-20 03:26:35

如果您只想将其用于 instanceOf,我认为您应该考虑使用此结构:

Object someObject = new Book(...);

if(someObject instanceOf Book book) {
    //use book as variable
    book.read();
}

据我所知,这称为模式匹配,这在 Java 14 中是可能的。

If you are only going to use it for instanceOf i think you should think about using this structure:

Object someObject = new Book(...);

if(someObject instanceOf Book book) {
    //use book as variable
    book.read();
}

To my knowledge this is called Pattern Matching is is possible in Java 14.

驱逐舰岛风号 2025-01-20 03:26:35

最接近您最初要求的内容是这样的:(

   Class<?> clazz = Book.class;

   Object someObject = new Book(...);
   
   if (clazz.isInstance(someObject)) {
      Object instanceOfClazz = clazz.cast(someObject);
      // ...
   }

请注意,此问答 - 有什么东西吗?就像Java中的instanceOf(Class c)? - 直接回答问题标题中的问题。)

但是您反对 cast 调用的结果:

“将丢失 Book 类的所有方法”

首先,这在技术上是不正确的。 instanceOfClazz 引用的对象仍然是并且将始终保持为 Book。它仍然具有并将永远具有Book 的所有方法。

但你确实有道理(我认为)。您无法在上述代码中有效地使用 cast 调用的结果,因为您将其分配给了类型为 Object 的变量。并且您无法通过静态类型为Object的变量/值调用Book方法。

如果我们这样写:

   Class<Book> clazz = Book.class;

   Object someObject = new Book(...);
   
   if (clazz.isInstance(someObject)) {
      Book book = clazz.cast(someObject);
      // call some `Book` methods.
   }

现在您可以在 book 上调用 Book 方法。但问题是我们必须编写 Class 而不是 Class (或 Class)才能实现这一点。所以我们最终还是将类名 Book 连接到代码中。哎呀!

根本问题是 Java 代码无法对对象进行常规方法调用,除非编译器知道它的类型是什么……并且它具有这些方法。如果您想在变量的静态类型为(例如)Object 的情况下调用 Book 方法,那么您必须使用反射来完成此操作。像这样的事情:

  if (clazz.isInstance(someObject)) {
      Method method = clazz.getMethod("setNosPages", int.class);
      method.invoke(someObject, 99);
  }

并处理可能抛出的各种异常。

基本上,您可以在代码中通过名称引用类和方法,或者使用反射。


“我需要将从 json 解析的对象/值分配给另一个类的 Book 类型(或相应的其他类型)字段。”

这是行不通的。 Java 是一种静态类型语言2。想想另一种方法来解决问题。例如,使用反射来给字段赋值。


1 - 这就是......你的问题最初问的是什么!
2 - 好吧……这过于简单化了。

The closest to what you originally asked1 for is something like this:

   Class<?> clazz = Book.class;

   Object someObject = new Book(...);
   
   if (clazz.isInstance(someObject)) {
      Object instanceOfClazz = clazz.cast(someObject);
      // ...
   }

(Note that this Q&A - Is there something like instanceOf(Class<?> c) in Java? - directly answers the question in the your question title.)

But you objected that the result of the cast call:

"would lose all the methods of the Book class".

First of all that is not technically correct. The object that instanceOfClazz refers to is still and will always remain a Book. It still has and will always have all of the methods of a Book.

But you do have a point (I think). You cannot use the cast call's result effectively in the above code because you assigned it to a variable whose type is Object. And you cannot call Book methods via a variable / value whose static type is Object.

If instead we had written this:

   Class<Book> clazz = Book.class;

   Object someObject = new Book(...);
   
   if (clazz.isInstance(someObject)) {
      Book book = clazz.cast(someObject);
      // call some `Book` methods.
   }

Now you can call Book methods on book. But the gotcha is that we had to write Class<Book> instead of Class<?> (or Class) to make that work. So we have ended up wiring the class name Book into the code anyway. Ooops!

The fundamental problem is that Java code cannot make regular method calls on an object unless the compiler knows what its type is ... and that it has those methods. If you want to invoke Book methods in cases where the static type of the variable is (say) Object, then you have to use reflection to do it. Something like this:

  if (clazz.isInstance(someObject)) {
      Method method = clazz.getMethod("setNosPages", int.class);
      method.invoke(someObject, 99);
  }

and deal with the various exceptions that that might throw.

Basically, you refer to the class and methods by name in the code, or you use reflection.


"I need to assign the object/value parsed from a json to a field of type Book (or other types accordingly) of another class."

It won't work. Java is a statically typed language2. Think of another way to solve the problem. For example, use reflection to assign to the field.


1 - That is ... what the words of your question originally asked!
2 - OK ... that is over-simplifying.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文