Java:将子包对象作为子对象添加至主包中的父对象
Hey there! Let's tackle this issue you're facing where your code works when the parent and child classes are in the same package, but breaks when the child is in a subpackage of the parent's package.
Why This Happens
Your current code uses reflective access via eGet and getEAllReferences(), which runs into two key issues across packages:
- Package Access Restrictions: Java's default (package-private) access only allows classes in the exact same package to access members. Subpackages are considered separate packages, so your reflective call might be hitting permission barriers.
- Unsafe Generic Casting: The raw cast
((List<EObject>)...)is not type-safe, and cross-package class loading can exacerbate issues here, leading to unexpected runtime errors even if permissions were fixed.
Solutions to Try
1. Use EMF-Generated Type-Safe Getters (Recommended)
EMF generates dedicated getter methods for each reference in your model—this is the cleanest, safest approach. Instead of using reflective eGet, do this:
// Replace getYourReferenceList() with the actual getter generated for your FatherObject's reference fatherObject.getYourReferenceList().add(containedObject);
This method is public (if your model's EReference is set to public visibility) and avoids all the pitfalls of reflection. Just make sure in your .ecore model, the visibility of the reference in FatherObject is set to public before regenerating code.
2. Fix Reflective Access Permissions (If You Must Use Reflection)
If you absolutely need to stick with reflective access, you'll need to ensure the reference is accessible across packages:
// Get the target reference EReference targetReference = FatherObject.eClass().getEAllReferences().get(v); // First, verify the reference is modifiable if (!targetReference.isChangeable()) { throw new IllegalArgumentException("Cannot modify a non-changeable reference"); } // Force access to the eGet method if needed Method eGetMethod = EObject.class.getMethod("eGet", EStructuralFeature.class); eGetMethod.setAccessible(true); // Safely retrieve the list and add your object @SuppressWarnings("unchecked") List<EObject> targetList = (List<EObject>) eGetMethod.invoke(FatherObject, targetReference); targetList.add(containedObject);
Note: This bypasses encapsulation and is not ideal for production code—use it only as a last resort.
3. Verify Package Visibility Settings
Double-check that:
- Your
FatherObjectclass is marked aspublic(not package-private) in the main package. - The ContainedObject class in the subpackage is also
public, so it can be accessed from the main package.
Final Note
Sticking to EMF's generated type-safe methods will save you from permission headaches and type errors in the long run—it's designed to handle these cross-package scenarios correctly out of the box.
内容的提问来源于stack exchange,提问作者George

