OpenJDK / jigsaw / jake / jdk
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); + } + +}