Java method(方法)详解
- 何为method(方法):一个仅在被召唤时候才动弹的代码块。可以给它喂data或parameters。有专职功能的method,叫做functions
好处:真正干活的程序块只用写一次,下次调用就行。
比如System.out.print()就是一个系统提供的method(方法)
method(方法)结构为
修饰符(比如public static) 返回值类型(比如int/void/double) 方法名(比如add)(定义的输入信息data/parameters等)
{
内部算法
return xx;
}
注意 如果不需要返回值,那么返回值类型那里就不写int,double之类的,而是换成void;
如果并不是void类型,那么内部算法最后不要忘了要return一个值出来。
比如public static int add(int a, int b){...return xx;}
方法的特点:
- 在程序中被创建,在其他地方被引用
- 一个方法只做一个功能,便于后期扩展
- 方法的定义和调用
练习自己写一个method(方法),完成add功能,注意写static以便用户在其他位置能够调用这个add方法
package method;
public class Demo01 {
public static void main(String[] args) {
int sum=add(5,6);
System.out.println("sum is "+sum);
}
/*自建方法结构为
public static 返回值类型 方法名(输入数据)
{
内部算法
}
注意 如果不需要返回值,那么就不写int,double之类的,返回值类型那里写void
*/
public static int add(int a, int b){
return a+b;
}
}
sum is 11
补充知识点:值传递和引用传递的对比
注意注意注意 java只有值传递
Pass By Reference (vs) Pass By Value(java only have this)
区别就是一人一个存储单元,还是两人引用着同一个存储单元
值传递:使用两个不同的存储单元,执行中,形式参数值改变不会影响实际参数值。(Java中基本数据类型都是值传递,一个萝卜一个坑)
引用传递:实际为引用地址,实际参数和形式参数指向同一存储地址,执行中改变了形式参数,则一定会影响实际参数。
(简单的说,引用传递类似:两根线都连着同一个萝卜坑。
通过线去找萝卜坑,从而最终找到萝卜。
通过其中一根线,偷偷将萝卜坑里的萝卜换掉了,另一根线再去找的时候,就会发现萝卜怎么变了。)
Pass By Value 对比 pass by reference举例:
java只能值传递,便于理解这里就用C#举例
(下面Show1就是值传递,Show2是引用传递)
Console.Title ="C#值传递和引用传递的对比"
string str1 = "1111";
string str2 = "2222";
Show1(str1);
Show2(ref str2);
Console.WriteLine(str1);
Console.WriteLine(str2);
Console.ReadKey();
static void Show1(string param1)
{
param1 ="333333";
}
static void Show2(ref string param2)
{
param2 ="44444";
}
运行结果
1111
44444
- 方法重载
比如 两个方法都叫做add,一个是 add(int a, int b) 一个是add(double a,double b)
名字重合了 但是用户在调用的时候,只用写清楚调用的参数
比如 写调用add(5.6,7.9)那么系统会自动找(double a,double b)去使用,虽然重名,但不会混乱。
3. 命令行传参
有时候希望运行一个程序时候再传递给它消息,这要靠传递命令行参数给main()函数实现。
举例,使用main默认的数组args,给它赋值,再输出args数组刚才获得的内容。
package method;
public class Demo03 {
public static void main(String[] args) {
//args为定义的数组,args.lenth是数组的长度
for (int i = 0; i < args.length; i++) {
System.out.println("args["+i+"]:"+args[i]);
}
}
}
如何传递参数呢(简单的说 就是运行时候输入 命令行+参数),方法如下:
- 在IDEA中,先将java代码compile成class文件:
javac xxx.java
本例中,在/javadir/java_study/src/method路径的下面,用terminal(ubuntu的terminal或者IDEA下面也有terminal都可以), 使用命令javac Demo03.java
这样会生成一个Demo03.class文件 - 运行编译好的class文件
java class my_parameter(s)
注意
如果直接在这个文件夹下运行java XX报错,可能原因是程序最上面有个package method;运行时找不到想要调用的package,而现在路径已经在method文件夹里面了,自然找不到method文件夹。
比如错误提示类似这个:
dx@dx-UX330UAK:~/javadir/java_study/src/method$ java Demo03
Error: Could not find or load main class Demo03
Caused by: java.lang.NoClassDefFoundError: method/Demo03 (wrong name: Demo03)
在不改变程序的情况下解决方法为,在terminal中cd向上一级。
调用方法改为java method.Demo3 后面加上你的参数,
比如下面的例子,输入main的数组参数给了(10 20 30 40)
java method.Demo03 10 20 30 40
dx@dx-UX330UAK:~/javadir/java_study/src$ java method.Demo03 10 20 30 40
args[0]:10
args[1]:20
args[2]:30
args[3]:40
dx@dx-UX330UAK:~/javadir/java_study/src$
- 可变参数(参数为不定项)
使用方法为指定参数类型比如int/double后面直接加上省略号…三个点,不要有空格。然后才定义变量名字
一个方法只能指定一个可变参数,必须是方法的最后一个参数,其他普通的参数要在他之前声明。
比如 public static void printmax(int a, int, b double…numbers){… return xxx;}
举例 定义一个接收int的method,int数量不确定,依次打印刚刚输入method的int元素。
public class testjan05 {
public static void main(String[] args) {
testjan05 x = new testjan05();
//第一组注释 x.myprint();
//括号里面可以为空,当没有输入参数时候,下面的System.out.println(ca)输出的就是对象的存储地址,为[I@27716f4
x.myprint(12,34,56); //第二 组注释
//括号里面给参数12,34,56时,下面用System.out.println(ca[0或1或2])时,输出的就是对象的内容,为
}
public void myprint(int... ca) {
//第一组注释 System.out.println(ca);//这个结果会是一个对象的存储地址,想要查看具体的数值应该看ca[0],ca[1]...
System.out.println(ca[0]); //第二 组注释
System.out.println(ca[1]); //第二 组注释
System.out.println(ca[2]); //第二 组注释
//System.out.println(ca[3]); //第二 组注释
//System.out.println(ca[4]); //第二 组注释
//System.out.println(ca[5]); //第二 组注释
//System.out.println(ca[6]); //第二 组注释
}
}
运行结果:
当前运算结果为:
12
34
56
如果将程序程序改动:
使用 x.myprint()不给输入参数;
并且myprint内部使用System.out.println(ca)等待输出结果,terminal结果显示为
[I@27716f4
练习二:定义一个接收不限数量int的method,查找输出其中最大的一个元素
public class testjan05{
public static void main(String[] args) {
testjan05 x = new testjan05();
x.printmax(82,3,42,53,33,6,33,55,66);
}
public void printmax(int... c) {
if (c.length == 0)
System.out.println("No valid input");
else{
int reg1=c[0];
for (int i = 0; i < c.length; i++) {
if (c[i]>reg1)
reg1 = c[i];
//System.out.println("c["+i+"]= "+c[i]);
}
System.out.println(reg1);
}
}
}
运行结果
82
练习三:下面的报错是什么意思?
package method;
public class Demo04 {
public static void main(String[] args) {
Demo04 x=new Demo04();
x.test(1,2,3,67,89,4,6,7,9);
}
public void test(int... i) {
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
System.out.println(i[3]);
System.out.println(i[4]);
System.out.println(i[5]);
System.out.println(i[6]);
System.out.println(i[7]);
System.out.println(i[8]);
System.out.println(i[9]);
System.out.println(i[10]);
System.out.println(i[11]);
}
}
输出结果
1
2
3
67
89
4
6
7
9
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 9 out of bounds for length 9
at method.Demo04.test(Demo04.java:19)
at method.Demo04.main(Demo04.java:6)
Process finished with exit code 1
注意 上面的输出结果报错,原因是定义数组时候最后一位9之后,再没内容了,所以出现了out of bounds for length的错误