Path: blob/master/test/jdk/java/beans/Introspector/OverriddenGenericSetter.java
41149 views
/*1* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.beans.BeanInfo;24import java.beans.Introspector;25import java.beans.PropertyDescriptor;26import java.lang.reflect.Method;2728/**29* @test30* @bug 819637331* @summary Introspector should work with overridden generic setter method32*/33public final class OverriddenGenericSetter {3435static class Parent<T> {36private T value;37public final T getValue() {return value;}38protected void setValue(T value) {this.value = value;}39}4041static class ChildO extends Parent<Object> {42public ChildO() {}43@Override44public void setValue(Object value) {super.setValue(value);}45}4647// For overridden setXXX javac will generate the "synthetic bridge" method48// setValue(Ljava/lang/Object). We will use two different types which may be49// placed before/after bridge method.50static class ChildA extends Parent<ArithmeticException> {51public ChildA() {}52@Override53public void setValue(ArithmeticException value) {super.setValue(value);}54}5556static class ChildS extends Parent<String> {57public ChildS() {}58@Override59public void setValue(String value) {super.setValue(value);}60}6162public static void main(String[] args) throws Exception {63testBehaviour(ChildA.class);64testBehaviour(ChildO.class);65testBehaviour(ChildS.class);66testProperty(ChildA.class, ArithmeticException.class);67testProperty(ChildO.class, Object.class);68testProperty(ChildS.class, String.class);69}7071private static void testBehaviour(Class<?> beanClass) throws Exception {72BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class);73PropertyDescriptor pd = beanInfo.getPropertyDescriptors()[0];74Object bean = beanClass.getConstructor().newInstance();75Method readMethod = pd.getReadMethod();76Method writeMethod = pd.getWriteMethod();7778// check roundtrip for default null values79writeMethod.invoke(bean,readMethod.invoke(bean));80writeMethod.invoke(bean,readMethod.invoke(bean));8182// set property to non-default value83// check roundtrip for non-default values84Object param = pd.getPropertyType().getConstructor().newInstance();85writeMethod.invoke(bean, param);86writeMethod.invoke(bean, readMethod.invoke(bean));87writeMethod.invoke(bean, readMethod.invoke(bean));88}8990private static void testProperty(Class<?> beanClass, Class<?> type) throws Exception {91BeanInfo beanInfo = Introspector.getBeanInfo(beanClass, Object.class);92PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();93if (pds.length != 1) {94throw new RuntimeException("Wrong number of properties");95}96PropertyDescriptor pd = pds[0];97System.out.println("pd = " + pd);98String name = pd.getName();99if (!name.equals("value")) {100throw new RuntimeException("Wrong name: " + name);101}102Class<?> propertyType = pd.getPropertyType();103if (propertyType != type) {104throw new RuntimeException("Wrong property type: " + propertyType);105}106Method readMethod = pd.getReadMethod();107if (readMethod == null) {108throw new RuntimeException("Read method is null");109}110Class<?> returnType = readMethod.getReturnType();111if (returnType != Object.class) {112throw new RuntimeException("Wrong return type; " + returnType);113}114Method writeMethod = pd.getWriteMethod();115if (writeMethod == null) {116throw new RuntimeException("Write method is null");117}118Class<?>[] parameterTypes = writeMethod.getParameterTypes();119if (parameterTypes.length != 1) {120throw new RuntimeException("Wrong parameters " + parameterTypes);121}122if (parameterTypes[0] != type) {123throw new RuntimeException("Wrong type: " + parameterTypes[0]);124}125}126}127128129