Using reflection to create a "builder pattern" (Joshua Bloch)

When trying to use Joshua Bloch "Pattern Builder" [clause 2 in "Effective Java Second Edition"] with reflection [ object = constructors [index] .newInstance (constructorParameterValues); ] the following exception is thrown:

java.lang.IllegalAccessException: class info.soaj.core.util.SjUtilReflection cannot access member of class info.soaj.core.attribute.SjAttributesForThrowable with modifiers "private"

Note. It is allowed. The accessible (private) constructor was discarded and an attempt was made to make it impossible (override = false). Bottom line: programmer error

Below is an example of a building class:

package info.soaj.core.attribute;

import info.soaj.core.attribute.internal.SjAttributesForStronglyTypedWrappers;
import info.soaj.core.internal.string.SjPopulatedClassName;
import info.soaj.core.internal.string.SjPopulatedMethodName;
import info.soaj.core.util.internal.SjUtilThrowable;

import java.io.Serializable;

/**
 * <p>
 * The "Builder" pattern as documented by Joshua Bloch ("Effective Java" -
 * Second Edition) is utilized to handle the variable number of required and
 * optional parameters.
 * </p>
 * 
 * <p style="font-family:Verdana; font-size:10px; font-style:italic"> Copyright
 * (c) 2006 - 2008 by Global Technology Consulting Group, Inc. at <a
 * href="http://gtcGroup.com">gtcGroup.com </a>. </p>
 * 
 * @author MarvinToll@gtcGroup.com
 * @since v. 1.0
 */

public class SjAttributesExample implements Serializable {

    /** UID */
    private static final long serialVersionUID = 1L;

    /** The name of class throwing the exception. */
    protected final SjPopulatedClassName classname;

    /** The name of method throwing the exception. */
    protected final SjPopulatedMethodName methodname;

    /**
     * Suppresses logging; default is <code>false</code>.
     */
    protected final boolean suppressLoggingOnly;

    /**
     * Constructor - private
     * 
     * @param builderThrowable
     */
    private SjAttributesExample(final BuilderThrowable builderThrowable) {
        this.classname = builderThrowable.classname;
        this.methodname = builderThrowable.methodname;
        this.suppressLoggingOnly = builderThrowable.suppressLoggingOnly;
    }

    /**
     * This static member immutable class is used to implement the builder
     * pattern.
     * 
     * @author MarvinToll@gtcGroup.com
     * @since v. 1.0
     */
    public static class BuilderThrowable {

        /** Class name. */
        private static final String CLASS_NAME = BuilderThrowable.class
                .getName();

        // Required attributes.

        /** The name of class throwing the exception. */
        protected final SjPopulatedClassName classname;

        /** The name of method throwing the exception. */
        protected final SjPopulatedMethodName methodname;

        // Optional attributes.

        /** Prevents action from occurring. Default is false. */
        protected boolean suppressLoggingOnly = false;

        /**
         * Constructor
         * 
         * @param classname
         * @param methodname
         */
        public BuilderThrowable(final String classname, final String methodname) {

            super();

            final String Method_Name = "BuilderThrowable";

            // What happens when handling an exception throws an exception?
            try {

                this.classname = new SjPopulatedClassName(classname,
                        new SjAttributesForStronglyTypedWrappers(CLASS_NAME,
                                Method_Name));

                this.methodname = new SjPopulatedMethodName(methodname,
                        new SjAttributesForStronglyTypedWrappers(CLASS_NAME,
                                Method_Name));

            } catch (final RuntimeException e) {

                // Log the contextual details.
                SjUtilThrowable.logExceptionOccuredWhileThrowingException(
                        CLASS_NAME, Method_Name, e);

                throw e;
            }

            return;
        }

        /**
         * This method sets a flag to suppress logging.
         * 
         * @param isLoggingSuppressed
         * @return BuilderThrowable
         */
        public BuilderThrowable suppressLoggingOnly(
                final boolean isLoggingSuppressed) {

            this.suppressLoggingOnly = isLoggingSuppressed;

            return this;
        }

        /**
         * This method is used for instantiating this class.
         * 
         * @return SjAttributesForThrowable
         */
        @SuppressWarnings("synthetic-access")
        public SjAttributesExample build() {

            return new SjAttributesExample(this);
        }
    }

    /**
     * This method returns an attribute.
     * 
     * @return String - Returns the <code>classname</code> attribute.
     */
    public String getClassname() {
        return this.classname.getString();
    }

    /**
     * This method returns an attribute.
     * 
     * @return String - Returns the <code>methodname</code> attribute.
     */
    public String getMethodname() {
        return this.methodname.getString();
    }

    /**
     * This method returns an attribute.
     * 
     * @return boolean - Returns the <code>suppressLoggingOnly</code> attribute.
     */
    public boolean isLoggingSuppressed() {
        return this.suppressLoggingOnly;
    }
}

      

+1


source to share


1 answer


Note. It is allowed. The accessible (private) constructor was discarded and an attempt was made to make it impossible (override = false). Bottom line: programmer error



0


source







All Articles