mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8302260: VarHandle.describeConstable() fails to return a nominal descriptor for static public fields
Reviewed-by: alanb, psandoz
This commit is contained in:
parent
ca73f7e80f
commit
9c202a5a8f
7 changed files with 254 additions and 39 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -114,52 +114,53 @@ final class VarHandles {
|
||||||
if (UNSAFE.shouldBeInitialized(refc))
|
if (UNSAFE.shouldBeInitialized(refc))
|
||||||
UNSAFE.ensureClassInitialized(refc);
|
UNSAFE.ensureClassInitialized(refc);
|
||||||
|
|
||||||
|
Class<?> decl = f.getDeclaringClass();
|
||||||
Object base = MethodHandleNatives.staticFieldBase(f);
|
Object base = MethodHandleNatives.staticFieldBase(f);
|
||||||
long foffset = MethodHandleNatives.staticFieldOffset(f);
|
long foffset = MethodHandleNatives.staticFieldOffset(f);
|
||||||
if (!type.isPrimitive()) {
|
if (!type.isPrimitive()) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleReferences.FieldStaticReadOnly(refc, base, foffset, type)
|
? new VarHandleReferences.FieldStaticReadOnly(decl, base, foffset, type)
|
||||||
: new VarHandleReferences.FieldStaticReadWrite(refc, base, foffset, type));
|
: new VarHandleReferences.FieldStaticReadWrite(decl, base, foffset, type));
|
||||||
}
|
}
|
||||||
else if (type == boolean.class) {
|
else if (type == boolean.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleBooleans.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleBooleans.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleBooleans.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleBooleans.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == byte.class) {
|
else if (type == byte.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleBytes.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleBytes.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleBytes.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleBytes.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == short.class) {
|
else if (type == short.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleShorts.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleShorts.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleShorts.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleShorts.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == char.class) {
|
else if (type == char.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleChars.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleChars.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleChars.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleChars.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == int.class) {
|
else if (type == int.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleInts.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleInts.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleInts.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleInts.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == long.class) {
|
else if (type == long.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleLongs.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleLongs.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleLongs.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleLongs.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == float.class) {
|
else if (type == float.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleFloats.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleFloats.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleFloats.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleFloats.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else if (type == double.class) {
|
else if (type == double.class) {
|
||||||
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
|
||||||
? new VarHandleDoubles.FieldStaticReadOnly(refc, base, foffset)
|
? new VarHandleDoubles.FieldStaticReadOnly(decl, base, foffset)
|
||||||
: new VarHandleDoubles.FieldStaticReadWrite(refc, base, foffset));
|
: new VarHandleDoubles.FieldStaticReadWrite(decl, base, foffset));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
@ -183,10 +184,10 @@ final class VarHandles {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required by instance static field handles
|
// Required by instance static field handles
|
||||||
static Field getStaticFieldFromBaseAndOffset(Class<?> receiverType,
|
static Field getStaticFieldFromBaseAndOffset(Class<?> declaringClass,
|
||||||
long offset,
|
long offset,
|
||||||
Class<?> fieldType) {
|
Class<?> fieldType) {
|
||||||
for (Field f : receiverType.getDeclaredFields()) {
|
for (Field f : declaringClass.getDeclaredFields()) {
|
||||||
if (!Modifier.isStatic(f.getModifiers())) continue;
|
if (!Modifier.isStatic(f.getModifiers())) continue;
|
||||||
|
|
||||||
if (offset == UNSAFE.staticFieldOffset(f)) {
|
if (offset == UNSAFE.staticFieldOffset(f)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -382,21 +382,21 @@ final class VarHandle$Type$s {
|
||||||
|
|
||||||
|
|
||||||
static sealed class FieldStaticReadOnly extends VarHandle {
|
static sealed class FieldStaticReadOnly extends VarHandle {
|
||||||
final Class<?> receiverType;
|
final Class<?> declaringClass;
|
||||||
final Object base;
|
final Object base;
|
||||||
final long fieldOffset;
|
final long fieldOffset;
|
||||||
#if[Object]
|
#if[Object]
|
||||||
final Class<?> fieldType;
|
final Class<?> fieldType;
|
||||||
#end[Object]
|
#end[Object]
|
||||||
|
|
||||||
FieldStaticReadOnly(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
||||||
this(receiverType, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false);
|
this(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadOnly.FORM, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FieldStaticReadOnly(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
protected FieldStaticReadOnly(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
||||||
VarForm form, boolean exact) {
|
VarForm form, boolean exact) {
|
||||||
super(form, exact);
|
super(form, exact);
|
||||||
this.receiverType = receiverType;
|
this.declaringClass = declaringClass;
|
||||||
this.base = base;
|
this.base = base;
|
||||||
this.fieldOffset = fieldOffset;
|
this.fieldOffset = fieldOffset;
|
||||||
#if[Object]
|
#if[Object]
|
||||||
|
@ -408,14 +408,14 @@ final class VarHandle$Type$s {
|
||||||
public FieldStaticReadOnly withInvokeExactBehavior() {
|
public FieldStaticReadOnly withInvokeExactBehavior() {
|
||||||
return hasInvokeExactBehavior()
|
return hasInvokeExactBehavior()
|
||||||
? this
|
? this
|
||||||
: new FieldStaticReadOnly(receiverType, base, fieldOffset{#if[Object]?, fieldType}, vform, true);
|
: new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, vform, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldStaticReadOnly withInvokeBehavior() {
|
public FieldStaticReadOnly withInvokeBehavior() {
|
||||||
return !hasInvokeExactBehavior()
|
return !hasInvokeExactBehavior()
|
||||||
? this
|
? this
|
||||||
: new FieldStaticReadOnly(receiverType, base, fieldOffset{#if[Object]?, fieldType}, vform, false);
|
: new FieldStaticReadOnly(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, vform, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -426,11 +426,11 @@ final class VarHandle$Type$s {
|
||||||
|
|
||||||
// Reflect on this VarHandle to extract the field name
|
// Reflect on this VarHandle to extract the field name
|
||||||
var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
|
var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
|
||||||
receiverType, fieldOffset, {#if[Object]?fieldType:$type$.class});
|
declaringClass, fieldOffset, {#if[Object]?fieldType:$type$.class});
|
||||||
var receiverTypeRef = staticField.getDeclaringClass().describeConstable();
|
var declaringTypeRef = declaringClass.describeConstable();
|
||||||
if (!receiverTypeRef.isPresent())
|
if (!declaringTypeRef.isPresent())
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
return Optional.of(VarHandleDesc.ofStaticField(receiverTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
|
return Optional.of(VarHandleDesc.ofStaticField(declaringTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -471,27 +471,27 @@ final class VarHandle$Type$s {
|
||||||
|
|
||||||
static final class FieldStaticReadWrite extends FieldStaticReadOnly {
|
static final class FieldStaticReadWrite extends FieldStaticReadOnly {
|
||||||
|
|
||||||
FieldStaticReadWrite(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType}) {
|
||||||
this(receiverType, base, fieldOffset{#if[Object]?, fieldType}, false);
|
this(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FieldStaticReadWrite(Class<?> receiverType, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
private FieldStaticReadWrite(Class<?> declaringClass, Object base, long fieldOffset{#if[Object]?, Class<?> fieldType},
|
||||||
boolean exact) {
|
boolean exact) {
|
||||||
super(receiverType, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact);
|
super(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, FieldStaticReadWrite.FORM, exact);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldStaticReadWrite withInvokeExactBehavior() {
|
public FieldStaticReadWrite withInvokeExactBehavior() {
|
||||||
return hasInvokeExactBehavior()
|
return hasInvokeExactBehavior()
|
||||||
? this
|
? this
|
||||||
: new FieldStaticReadWrite(receiverType, base, fieldOffset{#if[Object]?, fieldType}, true);
|
: new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FieldStaticReadWrite withInvokeBehavior() {
|
public FieldStaticReadWrite withInvokeBehavior() {
|
||||||
return !hasInvokeExactBehavior()
|
return !hasInvokeExactBehavior()
|
||||||
? this
|
? this
|
||||||
: new FieldStaticReadWrite(receiverType, base, fieldOffset{#if[Object]?, fieldType}, false);
|
: new FieldStaticReadWrite(declaringClass, base, fieldOffset{#if[Object]?, fieldType}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ForceInline
|
@ForceInline
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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
|
||||||
|
* @bug 8302260
|
||||||
|
* @build p.C p.D p.I p.q.Q
|
||||||
|
* @run junit DescribeConstableTest
|
||||||
|
* @summary Test VarHandle::describeConstable on static fields
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.constant.ClassDesc;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodHandles.Lookup;
|
||||||
|
import java.lang.invoke.VarHandle;
|
||||||
|
import java.lang.invoke.VarHandle.VarHandleDesc;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class DescribeConstableTest {
|
||||||
|
private static final Lookup LOOKUP = MethodHandles.lookup();
|
||||||
|
private static Stream<Arguments> testCases() {
|
||||||
|
return Stream.of(
|
||||||
|
// static field defined in p.C only
|
||||||
|
Arguments.of(p.C.class, "cString", String.class, p.C.class, "CClass"),
|
||||||
|
// static fields defined in both superinterface p.I and superclass p.q.Q
|
||||||
|
// resolved to the one defined in the direct superinterface of C
|
||||||
|
Arguments.of(p.C.class, "stringField", String.class, p.I.class, "I"),
|
||||||
|
Arguments.of(p.C.class, "longField", long.class, p.I.class, 10L),
|
||||||
|
// static fields defined in superclass p.q.Q only
|
||||||
|
Arguments.of(p.C.class, "stringField2", String.class, p.q.Q.class, "QClass2"),
|
||||||
|
Arguments.of(p.C.class, "longField2", long.class, p.q.Q.class, 102L),
|
||||||
|
// static fields defined in superinterface p.I only
|
||||||
|
Arguments.of(p.C.class, "stringField3", String.class, p.I.class, "I3"),
|
||||||
|
Arguments.of(p.C.class, "longField3", long.class, p.I.class, 13L),
|
||||||
|
// static fields defined in p.D only
|
||||||
|
Arguments.of(p.D.class, "dString", String.class, p.D.class, "DClass"),
|
||||||
|
Arguments.of(p.D.class, "dLong", long.class, p.D.class, 1L),
|
||||||
|
// static fields defined in both superinterface p.I and superclass p.q.Q
|
||||||
|
// resolved to the one defined in the direct superinterface of D
|
||||||
|
Arguments.of(p.D.class, "stringField", String.class, p.I.class, "I"),
|
||||||
|
Arguments.of(p.D.class, "longField", long.class, p.I.class, 10L)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("testCases")
|
||||||
|
void test(Class<?> refc, String name, Class<?> type, Class<?> declaringClass, Object value) throws Throwable {
|
||||||
|
var vh = LOOKUP.findStaticVarHandle(refc, name, type);
|
||||||
|
assertEquals(value, vh.get());
|
||||||
|
|
||||||
|
var refcDesc = refc.describeConstable().orElseThrow();
|
||||||
|
var typeDesc = type.describeConstable().orElseThrow();
|
||||||
|
var vhd = vh.describeConstable().orElseThrow();
|
||||||
|
var vhd2 = VarHandleDesc.ofStaticField(refcDesc, name, typeDesc);
|
||||||
|
|
||||||
|
assertEquals(value, vhd.resolveConstantDesc(LOOKUP).get());
|
||||||
|
assertEquals(value, vhd2.resolveConstantDesc(LOOKUP).get());
|
||||||
|
|
||||||
|
assertEquals(vhd.toString(), varHandleDescString(declaringClass, name, type, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
static String varHandleDescString(Class<?> declaringClass, String name, Class<?> type, boolean staticField) {
|
||||||
|
return String.format("VarHandleDesc[%s%s.%s:%s]",
|
||||||
|
staticField ? "static " : "",
|
||||||
|
declaringClass.describeConstable().orElseThrow().displayName(), name,
|
||||||
|
type.describeConstable().orElseThrow().displayName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package p;
|
||||||
|
|
||||||
|
public class C extends p.q.Q implements I {
|
||||||
|
public static String cString = "CClass";
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package p;
|
||||||
|
|
||||||
|
public class D extends p.q.Q implements I {
|
||||||
|
public static String dString = "DClass";
|
||||||
|
public static long dLong = 1L;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package p;
|
||||||
|
|
||||||
|
public interface I {
|
||||||
|
String stringField = "I";
|
||||||
|
long longField = 10l;
|
||||||
|
|
||||||
|
String stringField3 = "I3";
|
||||||
|
long longField3 = 13L;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package p.q;
|
||||||
|
|
||||||
|
public class Q {
|
||||||
|
public static String stringField = "QClass";
|
||||||
|
public static long longField = 100L;
|
||||||
|
|
||||||
|
public static String stringField2 = "QClass2";
|
||||||
|
public static long longField2 = 102L;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue