Java implements sample code sharing using reflection in visitor mode
The collection type is in Oriented to ObjectsProgramming is very commonly used, which also brings some code-related questions, such as, "How to operate different types of objects in the collection? ”
One approach is to iterate through each element in the collection and then perform specific operations based on its type. This will be very complicated, especially when you don’t know the type of the elements in the collection. If y wants To print the elements in the collection, you can write a method like this:
public void messyPrintCollection(Collection collection) { Iterator iterator = collection.iterator() while (iterator.hasNext()) System.out.println(iterator.next().toString()) }
It seems simple. It just calls the Object.toString() method and prints out the object, right? But what if your collection is a What about vectors containing hashtables? That gets more complicated. You have to check the type of the collection return object:
public void messyPrintCollection(Collection collection) { Iterator iterator = collection.iterator() while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof Collection) messyPrintCollection((Collection)o); else System.out.println(o.toString()); } }
OK, now you can handle the characters returned by other objects. String is not what you want? If you want to add quotes to the string object and add an f after the Float object, what should you do?
public void messyPrintCollection(Collection collection) { Iterator iterator = collection.iterator() while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof Collection) messyPrintCollection((Collection)o); else if (o instanceof String) System.out.println("'"+o.toString()+"'"); else if (o instanceof Float) System.out.println(o.toString()+"f"); else System.out.println(o.toString()); } }
The code becomes cluttered quickly. You don’t want the code to contain a lot of if-else statements! How to avoid it? Visitor pattern can help you. ##To implement the visitor pattern, you need to create a Visitor
interface and create a Visitable interface for the visited collection object. Next, you need to create a specific class to implement the Visitor and Visitable interfaces. It is roughly as follows: public interface Visitor
{
public void visitCollection(Collection collection);
public void visitString(String string);
public void visitFloat(Float float);
}
public interface Visitable
{
public void accept(Visitor visitor);
}
public class VisitableString implements Visitable { private String value; public VisitableString(String string) { value = string; } public void accept(Visitor visitor) { visitor.visitString(this); } }
In the accept method, according to different types, call the corresponding method in the visitor:
visitor.visitString(this)The specific implementation of Visitor is as follows:
public class PrintVisitor implements Visitor { public void visitCollection(Collection collection) { Iterator iterator = collection.iterator(); while (iterator.hasNext()) { Object o = iterator.next(); if (o instanceof Visitable) ((Visitable)o).accept(this); } public void visitString(String string) { System.out.println("'"+string+"'"); } public void visitFloat(Float float) { System.out.println(float.toString()+"f"); } }
At that time, as long as the VisitableFloat class and VisitableCollection class are implemented and the appropriate visitor method is called , you can get rid of the messyPrintCollection method that contains a bunch of if-else structures, and implement the same function in a very refreshing way. The visitCollection() method calls Visitable.accept(this), and the accept() method does the opposite. The correct method in the visitor is called. This is double dispatch: Visitor calls a method in the Visitable class, which in turn calls a method in the Visitor class.
Although after implementing visitor, if-else The statement is gone, but it still introduces a lot of additional code. It's annoying that you have to wrap the original objects, String and Float, into a class that implements the Visitable interface. You can restrict the visited collection to only contain Visitable objects.
However, there is still a lot of additional work to be done. Even worse, what do you do when you want to add a new Visitable type, such as VisitableInteger? This is a major drawback of the visitor pattern. If you want to add a new Visitable type, you have to change the Visitor interface and every class that implements the Visitor interface methods. You can not design Visitor as an interface. Instead, you can design Visitor as an abstract base class with
No operation. This is very similar to the Adapter class in Java GUI. The problem with doing this is that you will exhaust the single inheritance, and a common situation is that you also want to use inheritance to implement other functions, such as inheriting the StringWriter class. This again can only successfully access objects that implement the Visitable interface. Fortunately, Java can make your visitor pattern more flexible, and you can add Visitable objects as you wish. How to achieve it? The answer is to use reflection. The ReflectiveVisitor interface using reflection only requires one method:
public interface ReflectiveVisitor { public void visit(Object o); }
Okay, the above is very simple. The Visitable interface will not be used for now, I will talk about it later. Now, I implement PrintVisitor class using reflection.
public class PrintVisitor implements ReflectiveVisitor { public void visitCollection(Collection collection) { ... same as above ... } public void visitString(String string) { ... same as above ... } public void visitFloat(Float float) { ... same as above ... } public void default(Object o) { System.out.println(o.toString()); } public void visit(Object o) { // Class.getName() returns package information as well. // This strips off the package information giving us // just the class name String methodName = o.getClass().getName(); methodName = "visit"+ methodName.substring(methodName.lastIndexOf('.')+1); // Now we try to invoke the method visit<methodName> try { // Get the method visitFoo(Foo foo) Method m = getClass().getMethod(methodName, new Class[] { o.getClass() }); // Try to invoke visitFoo(Foo foo) m.invoke(this, new Object[] { o }); } catch (NoSuchMethodException e) { // No method, so do the default implementation default(o); } } }
Now you don’t need to use the Visitable wrapper class (which wraps the original types String and Float). You can access visit() directly and it will call the correct method. One advantage of visit() is that it dispatches the method it sees fit. This doesn't necessarily use reflection, it could use a completely different mechanism.
In the new PrintVisitor class, there are operation methods corresponding to Collections, String and Float; for types that cannot be processed, they can be captured through catch statements. For types that cannot be handled, you can try to handle all their superclasses by extending the visit() method. First, add a new method getMethod(Class c), and the return value is a method that can be triggered. It will
search
Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

PHP is a scripting language widely used on the server side, especially suitable for web development. 1.PHP can embed HTML, process HTTP requests and responses, and supports a variety of databases. 2.PHP is used to generate dynamic web content, process form data, access databases, etc., with strong community support and open source resources. 3. PHP is an interpreted language, and the execution process includes lexical analysis, grammatical analysis, compilation and execution. 4.PHP can be combined with MySQL for advanced applications such as user registration systems. 5. When debugging PHP, you can use functions such as error_reporting() and var_dump(). 6. Optimize PHP code to use caching mechanisms, optimize database queries and use built-in functions. 7

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHP is suitable for web development, with simple syntax and high execution efficiency. 2. Python is suitable for data science and machine learning, with concise syntax and rich libraries.

PHP is suitable for web development, especially in rapid development and processing dynamic content, but is not good at data science and enterprise-level applications. Compared with Python, PHP has more advantages in web development, but is not as good as Python in the field of data science; compared with Java, PHP performs worse in enterprise-level applications, but is more flexible in web development; compared with JavaScript, PHP is more concise in back-end development, but is not as good as JavaScript in front-end development.

PHP and Python each have their own advantages and are suitable for different scenarios. 1.PHP is suitable for web development and provides built-in web servers and rich function libraries. 2. Python is suitable for data science and machine learning, with concise syntax and a powerful standard library. When choosing, it should be decided based on project requirements.

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

The reasons why PHP is the preferred technology stack for many websites include its ease of use, strong community support, and widespread use. 1) Easy to learn and use, suitable for beginners. 2) Have a huge developer community and rich resources. 3) Widely used in WordPress, Drupal and other platforms. 4) Integrate tightly with web servers to simplify development deployment.
