Exforsys.com
 
Home Certification SCJP
 

SCJP 5: Chapter 1. Declarations, Initialization and Scoping (Part-4)

 

Chapter 1. Declarations, Initialization and Scoping (Part-4)

Develop code that declares both static and non-static methods, and - if appropriate - use method names that adhere to the JavaBeans naming standards. Also develop code that declares and uses a variable-length argument list.

In this tutorial you will learn about Varargs, Overloading resolution, Varargs and overloading, Varargs and overriding.


 



To set or get an instance variable, use methods with the names setVariable(...) and getVariable() for variables named variable:


private Object variable;
public void setVariable(Object var) {...}
public Object getVariable() {...}


For boolean instance variables you may provide a getter method named is... or has... that returns a boolean, that can be used conveniently in boolean expressions:


private boolean enabled;
public void setEnabled(boolean aBoolean) {...}
public boolean isEnabled() {...}


Varargs

In past releases, a method that took an arbitrary number of values required you to create an array and put the values into the array prior to invoking the method.


It is still true that multiple arguments must be passed in an array, but the varargs feature automates and hides the process. Furthermore, it is upward compatible with preexisting APIs. So, for example, a method now has this declaration:


method (type a, type b, type ... arguments);


The three periods after the final parameter's type indicate that the final argument may be passed as an array or as a sequence of arguments. Varargs can be used only in the final argument position.


See the following program for example:



public class VarArgs {

.....public static void main(String... args) {
..........printUs("ONE", "TWO", "THREE");
..........printUs("FOUR", "FIVE");
..........printUs(new String[]{"SIX", "SEVEN});
..........printUs(); // empty array is allowed too
.....}

.....private static void printUs(String... args) {
..........System.out.println("Var args method");
..........for (String s : args) {
...............System.out.println(s);
..........}
.....}

.....private static void printUs(String arg1, String arg2) {
..........System.out.println("Specific two argument method");
..........System.out.println(arg1);
..........System.out.println(arg2);
.....}
}



It produces the following output:


Var args method
ONE
TWO
THREE
Specific two argument method
FOUR
FIVE
Var args method
SIX
SEVEN
Var args method


Purpose: add methods that can be called with variable-length argument list.
Heavily employed in formatting text output, aiding internationalization.
Syntax and semantics:


  • the last formal parameter in a method declaration can be declared as:
    .
    ReferenceType ... FormalParameterName
    .
  • the last formal parameter in the method is then interpreted as having the type:
    .
    ReferenceType[]

// Method declaration
public static void publish(String str, Object ... data) // Object[]

// Method calls
publish("one"); // ("one", new Object[] {})
publish("one", "two"); // ("one", new Object[] {"two})
publish("one", "two", 3); // ("one", new Object[] {"two", new Integer(3)})



 


Some more varargs examples:


import static java.lang.System.out;
            public class VarargsDemo {
            .....public static void main(String ... args) {
            ..........int day = 1;
            ..........String month = "February";
            ..........int year = 2005;
            
..........flexiPrint(); // new Object[] {}
            ..........flexiPrint(day); // new Object[] {new Integer(day)}
            ..........flexiPrint(day, month); 
..........// new Object[] {new Integer(day), month} ..........flexiPrint(day, month, year);
..........// new Object[] {new Integer(day), month,
..........//new Integer(year)} .....} .....public static void flexiPrint(Object ... data) { // Object[] ..........out.println("No. of elements: " + data.length); ..........for (int i = 0; i < data.length; i++) { ...............out.print(data[i] + " "); ..........} ..........out.println(); .....} }


The output:


No. of elements: 0
No. of elements: 1
1
No. of elements: 2
1 February
No. of elements: 3
1 February 2005


Overloading resolution

Resolution of overloaded methods selects the most specific method for execution.


One method is more specific than another method if all actual parameters that can be accepted by the one can be accepted by the other. A method call can lead to an ambiguity between two or more overloaded methods, and is flagged by the compiler. Example:


...
            // The method 'flipFlop(String, int, Integer)' 
// is ambiguous for the type VarargsDemo flipFlop("(String, Integer, int)", new Integer(4), 2004);
// COMPILER ERROR! ...
private static void flipFlop(String str, int i, Integer iRef) {
            .....out.println(str + " ==> (String, int, Integer)");
            }

private static void flipFlop(String str, int i, int j) {
            .....out.println(str + " ==> (String, int, int)");
            }


This is a legal example:


...
            flipFlop("(String, Integer, int)", new Integer(4), 2004); // OK
            ...
            
private static void flipFlop(String str, Integer iRef,  int i) {
            .....out.println(str + " ==> (String, Integer, int)");
            }

private static void flipFlop(String str, int i, int j) {
            .....out.println(str + " ==> (String, int, int)");
            }


The output will be:


(String, Integer, int) == > (String, Integer, int)


Varargs and overloading

The example illustrates how the most specific overloaded method is chosen for a method call:


public class VarargsOverloading {
            .....public void operation(String str) {
            ..........String signature = "(String)";
            ..........out.println(str + " => " + signature);
            .....}
            
.....public void operation(String str, int m) {
            ..........String signature = "(String, int)";
            ..........out.println(str + " => " + signature);
            .....}

.....public void operation(String str, int m, int n) {
            ..........String signature = "(String, int, int)";
            ..........out.println(str + " => " + signature);
            .....}

.....public void operation(String str, Integer... data) {
            ..........String signature = "(String, Integer[])";
            ..........out.println(str + " => " + signature);
            .....}

.....public void operation(String str, Number... data) {
            ..........String signature = "(String, Number[])";
            ..........out.println(str + " => " + signature);
            .....}

.....public void operation(String str, Object... data) {
            ..........String signature = "(String, Object[])";
            ..........out.println(str + " => " + signature);
            .....}

.....public static void main(String[] args) {
            ..........VarargsOverloading ref = new VarargsOverloading();
            ..........ref.operation("1. (String)");
            ..........ref.operation("2. (String, int)", 10);
            ..........ref.operation("3. (String, Integer)", new Integer(10));
            ..........ref.operation("4. (String, int, byte)", 10, (byte) 20);
            ..........ref.operation("5. (String, int, int)", 10, 20);
            ..........ref.operation("6. (String, int, long)", 10, 20L);
            ..........ref.operation("7. (String, int, int, int)", 10, 20, 30);
            ..........ref.operation("8. (String, int, double)", 10, 20.0);
            ..........ref.operation("9. (String, int, String)", 10, "what?");
            ..........ref.operation("10.(String, boolean)", false);
            .....}
            }


The output:


1. (String) => (String)
2. (String, int) => (String, int)
3. (String, Integer) => (String, int)
4. (String, int, byte) => (String, int, int)
5. (String, int, int) => (String, int, int)
6. (String, int, long) => (String, Number[])
7. (String, int, int, int) => (String, Integer[])
8. (String, int, double) => (String, Number[])
9. (String, int, String) => (String, Object[])
10.(String, boolean) => (String, Object[])


Varargs and overriding

Overriding of varargs methods does not present any surprises as along as criteria for overriding is satisfied.


public class OneSuperclass {
            .....public int doIt(String str, Integer... data) 
.....throws java.io.EOFException, ...............java.io.FileNotFoundException { // (1) ..........String signature = "(String, Integer[])"; ..........out.println(str + " => " + signature); ..........return 1; .....}
.....public void doIt(String str, Number... data) { // (2)
            ..........String signature = "(String, Number[])";
            ..........out.println(str + " => " + signature);
            .....}
            }


import static java.lang.System.out;
            public class OneSubclass extends OneSuperclass {
            .....// public int doIt(String str, Integer[] data) 	
.....// Overridden (a) .....public int doIt(String str, Integer... data)
.....// Overridden (b) ...............throws java.io.FileNotFoundException { ..........String signature = "(String, Integer[])"; ..........out.println("Overridden: " + str + " => " + signature); ..........return 0; .....}
.....public void doIt(String str, Object... data) { 
.....// Overloading ..........String signature = "(String, Object[])"; ..........out.println(str + " => " + signature); .....}
.....public static void main(String[] args) throws Exception { ..........OneSubclass ref = new OneSubclass(); ..........ref.doIt("1. (String)"); ..........ref.doIt("2. (String, int)", 10); ..........ref.doIt("3. (String, Integer)", new Integer(10)); ..........ref.doIt("4. (String, int, byte)", 10, (byte) 20); ..........ref.doIt("5. (String, int, int)", 10, 20); ..........ref.doIt("6. (String, int, long)", 10, 20L); ..........ref.doIt("7. (String, int, int, int)", 10, 20, 30); ..........ref.doIt("8. (String, int, double)", 10, 20.0); ..........ref.doIt("9. (String, int, String)", 10, "what?"); ..........ref.doIt("10.(String, boolean)", false); .....} }


The output:


Overridden: 1. (String) => (String, Integer[])
Overridden: 2. (String, int) => (String, Integer[])
Overridden: 3. (String, Integer) => (String, Integer[])
4. (String, int, byte) => (String, Number[])
Overridden: 5. (String, int, int) => (String, Integer[])
6. (String, int, long) => (String, Number[])
Overridden: 7. (String, int, int, int) => (String, Integer[])
8. (String, int, double) => (String, Number[])
9. (String, int, String) => (String, Object[])
10.(String, boolean) => (String, Object[])



Another method signature:


...
public int doIt(String str, Integer[] data) // Overridden (a)
// public int doIt(String str, Integer... data) // Overridden (b)
...


However, the method will be invoked from superclass:


1. (String) => (String, Number[])
2. (String, int) => (String, Number[])
3. (String, Integer) => (String, Number[])
4. (String, int, byte) => (String, Number[])
5. (String, int, int) => (String, Number[])
6. (String, int, long) => (String, Number[])
7. (String, int, int, int) => (String, Number[])
8. (String, int, double) => (String, Number[])
9. (String, int, String) => (String, Object[])
10.(String, boolean) => (String, Object[])


______________


Author: Mikalai Zaikin. Please Click Here to visit Authors site for any updates and changes to the study notes.



Read Next: SCJP 5 : Chapter 1. Declarations, Initialization and Scoping (Part-5)



 

 

Comments



Post Your Comment:

Members Please Login
Your Name:*
e-mail ID:(required for notification)*
Image Verification: 
 
 Subscribe    

Sponsored Links

 

Subscribe via RSS


Get Daily Updates via Subscribe to Exforsys Free Training via email


Get Latest Free Training Updates delivered directly to your Inbox...

Enter your email address:


 

Subscribe to Exforsys Free Training via RSS
 

 
Partners -  Privacy and Legal Policy -  Site News -  Contact   Sitemap  

Copyright © 2000 - 2010 exforsys.com. All Rights Reserved

Page copy protected against web site content infringement by Copyscape