changeset 14498:1d2dd559597e

Part 1 of Class::getPackageName
author alanb
date Wed, 18 Nov 2015 16:47:05 +0000
parents c1a46b310ca2
children e8a58d7ea798
files src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/sun/reflect/Reflection.java test/java/lang/Class/getPackageName/Basic.java
diffstat 3 files changed, 239 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java	Wed Nov 18 15:15:34 2015 +0000
+++ b/src/java.base/share/classes/java/lang/Class.java	Wed Nov 18 16:47:05 2015 +0000
@@ -941,6 +941,46 @@
 
 
     /**
+     * Returns the fully qualified package name.
+     *
+     * If this class is a top level class, then this method returns the fully
+     * qualified name of the package that the class is a member of, or the
+     * empty string if the class is in an unnamed package.
+     *
+     * If this class is a member class, then this method is equivalent to
+     * invoking {@code getPackageName()} on the {@link #getEnclosingClass
+     * enclosing class}.
+     *
+     * If this class is a {@link #isLocalClass local class} or an {@link
+     * #isAnonymousClass() anonymous class}, then this method is equivalent to
+     * invoking {@code getPackageName()} on the {@link #getDeclaringClass
+     * declaring class} of the {@link #getEnclosingMethod enclosing method} or
+     * {@link #getEnclosingConstructor enclosing constructor}.
+     *
+     * This method returns {@code null} if this class represents an array type,
+     * a primitive type or void.
+     *
+     * @return the fully qualified package name
+     *
+     * @since 1.9
+     * @jls 6.7  Fully Qualified Names
+     */
+    public String getPackageName() {
+        String pn = this.packageName;
+        if (pn == null && !isArray() && !isPrimitive()) {
+            String cn = getName();
+            int dot = cn.lastIndexOf('.');
+            pn = (dot != -1) ? cn.substring(0, dot) : "";  // intern?
+            this.packageName = pn;
+        }
+        return pn;
+    }
+
+    // cached package name, this will eventually move to a helper type with module
+    private String packageName;
+
+
+    /**
      * Returns the interfaces directly implemented by the class or interface
      * represented by this object.
      *
--- a/src/java.base/share/classes/sun/reflect/Reflection.java	Wed Nov 18 15:15:34 2015 +0000
+++ b/src/java.base/share/classes/sun/reflect/Reflection.java	Wed Nov 18 16:47:05 2015 +0000
@@ -239,13 +239,11 @@
     }
 
     private static String packageName(Class<?> c) {
-        if (c.isArray()) {
-            return packageName(c.getComponentType());
+        String pn = c.getPackageName();
+        if (pn != null) {
+            return pn;
         } else {
-            String name = c.getName();
-            int dot = name.lastIndexOf('.');
-            if (dot == -1) return "";
-            return name.substring(0, dot);
+            throw new InternalError("Should not get here: " + c);
         }
     }
 
@@ -430,12 +428,7 @@
                 public Boolean run() {
                     String s;
                     s = System.getProperty("sun.reflect.debugModuleAccessChecks");
-                    if (s != null && !s.equalsIgnoreCase("false"))
-                        return true;
-
-                    // legacy property name, it cannot be used to disable checks
-                    s = System.getProperty("sun.reflect.enableModuleChecks");
-                    return "debug".equals(s);
+                    return (s != null && !s.equalsIgnoreCase("false"));
                 }
             };
             printStackWhenAccessFails = AccessController.doPrivileged(pa);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/lang/Class/getPackageName/Basic.java	Wed Nov 18 16:47:05 2015 +0000
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @compile Basic.java
+ * @run testng p.Basic
+ * @summary Basic test for java.lang.Class::getPackageName
+ */
+
+package p;
+
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import static org.testng.Assert.*;
+
+public class Basic {
+
+
+    // -- member classes --
+
+    static class Nested {
+        static class Foo { }
+    }
+
+    Class<?> getNestedClass1() {
+        return Nested.class;
+    }
+    Class<?> getNestedClass2() {
+        return Nested.Foo.class;
+    }
+
+    class Inner {
+        class Foo { }
+    }
+
+    Class<?> getInnerClass1() {
+        return Inner.class;
+    }
+    Class<?> getInnerClass2() {
+        return Inner.Foo.class;
+    }
+
+    // -- local and anonymous classes --
+
+    Class<?> getLocalClass1() {
+        class Local { }
+        return Local.class;
+    }
+
+    Class<?> getLocalClass2() {
+        class Local {
+            class Foo { }
+        }
+        return Local.Foo.class;
+    }
+
+    Class<?> getLocalClass3() {
+        class Local {
+            final Class<?> c;
+            Local() {
+                class Foo { }
+                this.c = Foo.class;
+            }
+            Class<?> get() {
+                return c;
+            }
+        }
+        return new Local().get();
+    }
+
+    Class<?> getAnonymousClass1() {
+        Runnable r = new Runnable() { public void run() { } };
+        return r.getClass();
+    }
+
+    Class<?> getAnonymousClass2() {
+        class Local {
+            Class<?> get() {
+                Runnable r = new Runnable() { public void run() { } };
+                return r.getClass();
+            }
+        }
+        return new Local().get();
+    }
+
+    Class<?> getAnonymousClass3() {
+        Runnable r = () -> { };
+        return r.getClass();
+    }
+
+    Class<?> getAnonymousClass4() {
+        class Local {
+            Class<?> get() {
+                Runnable r = () -> { };
+                return r.getClass();
+            }
+        }
+        return new Local().get();
+    }
+
+    Class<?> getAnonymousClass5() {
+        class Local {
+            final Class<?> c;
+            Local() {
+                Runnable r = new Runnable() { public void run() { } };
+                this.c = r.getClass();
+            }
+            Class<?> get() {
+                return c;
+            }
+        }
+        return new Local().get();
+    }
+
+    Class<?> getAnonymousClass6() {
+        class Local {
+            final Class<?> c;
+            Local() {
+                Runnable r = () -> { };
+                this.c = r.getClass();
+            }
+            Class<?> get() {
+                return c;
+            }
+        }
+        return new Local().get();
+    }
+
+    static final String TEST_PACKAGE = Basic.class.getPackage().getName();
+
+    @DataProvider(name = "classes")
+    public Object[][] classes() {
+        return new Object[][] {
+
+            { Basic.class,                  TEST_PACKAGE },
+            { Basic[].class,                null },
+            { Basic[][].class,              null },
+
+            { getNestedClass1(),            TEST_PACKAGE },
+            { getNestedClass2(),            TEST_PACKAGE },
+            { getInnerClass1(),             TEST_PACKAGE },
+            { getInnerClass2(),             TEST_PACKAGE },
+
+            { getLocalClass1(),             TEST_PACKAGE },
+            { getLocalClass2(),             TEST_PACKAGE },
+            { getLocalClass3(),             TEST_PACKAGE },
+
+            { getAnonymousClass1(),         TEST_PACKAGE },
+            { getAnonymousClass2(),         TEST_PACKAGE },
+            { getAnonymousClass3(),         TEST_PACKAGE },
+            { getAnonymousClass4(),         TEST_PACKAGE },
+            { getAnonymousClass5(),         TEST_PACKAGE },
+            { getAnonymousClass6(),         TEST_PACKAGE },
+
+            { Object.class,                 "java.lang" },
+            { Object[].class,               null },
+            { Object[][].class,             null },
+
+            { int.class,                    null },
+            { int[].class,                  null },
+            { int[][].class,                null },
+
+            { void.class,                   null },
+
+        };
+    }
+
+    @Test(dataProvider = "classes")
+    public void testPackageName(Class<?> type, String expected) {
+        assertEquals(type.getPackageName(), expected);
+    }
+
+}