javaextend.js revision 22:2a5c2258827b
1/* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/** 25 * @test 26 * @run 27 */ 28 29function model(n) { 30 return Java.type("jdk.nashorn.internal.test.models." + n) 31} 32 33// Can't extend a final class 34try { 35 Java.extend(model("FinalClass")) 36} catch(e) { 37 print(e) 38} 39 40// Can't extend a class with no public or protected constructor 41try { 42 Java.extend(model("NoAccessibleConstructorClass")) 43} catch(e) { 44 print(e) 45} 46 47// Can't extend a non-public class 48try { 49 Java.extend(model("NonPublicClass")) 50} catch(e) { 51 print(e) 52} 53 54// Make sure we can implement interfaces from the unnamed package 55var c = new (Java.extend(Java.type("UnnamedPackageTestCallback")))() { call: function(s) { return s + s } } 56print(c.call("abcd")) 57 58// Basic Runnable from an object 59new (Java.extend(java.lang.Runnable))({ run: function() { print("run-object") } }).run() 60 61// Basic Runnable from a function 62new (Java.extend(java.lang.Runnable))(function() { print("run-fn") }).run() 63 64// Basic Runnable from an autoconverted function 65var t = new java.lang.Thread(function() { print("run-fn-autoconvert") }) 66t.start() 67t.join() 68 69// SAM conversion should work on overloaded methods of same name 70var os = new (Java.extend(model("OverloadedSam")))(function(s1, s2) { print("overloaded-sam: " + s1 + ", " + s2) }) 71os.sam("x") 72os.sam("x", "y") 73 74// Test overriding of hashCode, equals, and toString 75var oo = Java.extend(model("OverrideObject")) 76// First, see non-overridden values 77print("oo-plain-hashCode: " + (new oo({})).hashCode()) 78print("oo-plain-toString: " + (new oo({})).toString()) 79print("oo-plain-equals : " + (new oo({})).equals({})) 80// Now, override them 81print("oo-overridden-hashCode: " + (new oo({ hashCode: function() { return 6 }})).hashCode()) 82print("oo-overridden-toString: " + (new oo({ toString: function() { return "override-object-overriden" }})).toString()) 83print("oo-overridden-equals : " + (new oo({ equals: function() { return true }})).equals({})) 84// Finally, test that equals and hashCode can be overridden with functions from a prototype, but toString() can't: 85function Proto() { 86 return this; 87} 88Proto.prototype = { 89 toString: function() { return "this-will-never-be-seen" }, // toString only overridden when it's own property, never from prototype 90 equals: function() { return true }, 91 hashCode: function() { return 7 } 92} 93print("oo-proto-overridden-hashCode: " + (new oo(new Proto())).hashCode()) 94print("oo-proto-overridden-toString: " + (new oo(new Proto())).toString()) 95print("oo-proto-overridden-equals : " + (new oo(new Proto())).equals({})) 96 97// Subclass a class with a protected constructor, and one that takes 98// additional constructor arguments (a token). Also demonstrates how can 99// you access the Java adapter instance from the script (just store it in the 100// scope, in this example, "cwa") to retrieve the token later on. 101var cwa = new (Java.extend(model("ConstructorWithArgument")))("cwa-token", function() { print(cwa.token) }) 102cwa.doSomething() 103 104// Do the same thing with proprietary syntax and object literal 105var cwa2 = new (model("ConstructorWithArgument"))("cwa2-token") { doSomething: function() { print("cwa2-" + cwa2.token ) } } 106cwa2.doSomething() 107