View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit.internal.expectations.mocking;
7   
8   import edu.umd.cs.findbugs.annotations.NonNull;
9   import edu.umd.cs.findbugs.annotations.Nullable;
10  
11  import mockit.internal.util.StackTrace;
12  
13  import org.objenesis.ObjenesisHelper;
14  
15  /**
16   * Factory for the creation of new mocked instances, and for obtaining/clearing the last instance created. There are
17   * separate subclasses dedicated to mocked interfaces and mocked classes.
18   */
19  public abstract class InstanceFactory {
20  
21      @NonNull
22      private final Class<?> concreteClass;
23      @Nullable
24      Object lastInstance;
25  
26      InstanceFactory(@NonNull Class<?> concreteClass) {
27          this.concreteClass = concreteClass;
28      }
29  
30      @NonNull
31      @SuppressWarnings("unchecked")
32      final <T> T newUninitializedConcreteClassInstance() {
33          try {
34              return (T) ObjenesisHelper.newInstance(concreteClass);
35          } catch (Exception e) {
36              StackTrace.filterStackTrace(e);
37              e.printStackTrace();
38              throw e;
39          }
40      }
41  
42      @NonNull
43      public abstract Object create();
44  
45      @Nullable
46      public final Object getLastInstance() {
47          return lastInstance;
48      }
49  
50      public abstract void clearLastInstance();
51  
52      static final class InterfaceInstanceFactory extends InstanceFactory {
53          @Nullable
54          private Object emptyProxy;
55  
56          InterfaceInstanceFactory(@NonNull Object emptyProxy) {
57              super(emptyProxy.getClass());
58              this.emptyProxy = emptyProxy;
59          }
60  
61          @NonNull
62          @Override
63          public Object create() {
64              if (emptyProxy == null) {
65                  emptyProxy = newUninitializedConcreteClassInstance();
66              }
67  
68              lastInstance = emptyProxy;
69              return emptyProxy;
70          }
71  
72          @Override
73          public void clearLastInstance() {
74              emptyProxy = null;
75              lastInstance = null;
76          }
77      }
78  
79      static final class ClassInstanceFactory extends InstanceFactory {
80          ClassInstanceFactory(@NonNull Class<?> concreteClass) {
81              super(concreteClass);
82          }
83  
84          @Override
85          @NonNull
86          public Object create() {
87              lastInstance = newUninitializedConcreteClassInstance();
88              return lastInstance;
89          }
90  
91          @Override
92          public void clearLastInstance() {
93              lastInstance = null;
94          }
95      }
96  }