不定程度自变量&(匿名)内部类&传值调用

不定长度自变量
在调用方法时,若方法的自变量个数事先无法决定该如何处理,例如 System. out. printf ()
方法就无法事先决定自变量个数:

 Sys tem. out. printf("&d",10)i
 System. out. printf("%d%d", 1020);
 system. out. printf("%d %d %d", 102030);

在JDK5之后支持不定长度自变量( Variable- Length Argument),可以轻松地解决这个问题:

    public static int sum(int...nums) {
        int sum=0;
        for(int num:nums) {
            sum+=num;
        }
        return sum;
    }

要使用不定长度自变量,声明参数列时要在类型关键字后加上…,在sum()方法通过用增强式for循环来取得不定长度自变量中的每个元素,可以这样使用:

 System. out. printin (sum(12))
 System. out. Println( sum(123))
 Sys tem. out. println (sum(1234))

实际上不定长度自变量是编译程序蜜糖,反编译后:int…声明的变量实际上展开为数组,而调用不定长度自变量客户端,例如out. printin(sum(12,3)),展开后也是变为数组当作自变量传递。这可以从反编译后的程序代码得知:

out.println(
 thtool. sum(new int[] (123)
)

使用不定长度自变量时,方法上声明的不定长度参数必须是参数列最后一个。例如以下是合法声明:

 public void some(int argl, int arg2, int... varargs){
 }

以下方式是不合法声明:

 public void some(Int... varargs, int argl, int arg2){}

使用两个及以上不定长度自变量也是不合法的:
如果使用对象的不定长度自变量,声明的方法相同。例如

public void some(Other... others){}

匿名内部类
可以在类中再定义类,这称为内部类。

class Some{
    class Other{
    }
}

要使用Some中的 other类必须先建立some实例

Some s=new Some;
Some.Other o = new s.new otner();

内部类也可以用public、 protected或 private声明。
内部类本身可以存取外部类的成员,通常非静态内部类会声明为 private,这类内部类是辅助类中某些操作而设计,外部不用知道内部类的存在。
内部类也可以声明为 static。例如:

class Some{
    static class Other{
    }
}

一个被声明为 statici的内部类,通常是将部类当作名称空间。可以这样建立类实例: Some Other o= new Some.Other();
被声明为 static的内部类,虽然将外部类当作名称空间,但算是个独立类,它可以存取外部类 static成员,但不可存取外部类非 static成员,

class Some{
    static int x;
    int y;
    static class Other{
        void doOther() {
            out.println(x);
            out.println(y);//这一行报错
        }
    }
}

方法中也可以声明类,这通常是辅助方法中演算之用,方法外无法使用。例如:

class Some{
     public void dosome(){
     class Other{}
    }
 }

在撰写Java程序时,经常会有临时继承某个类或操作某个接口并建立实例的需求。由于这类子类或接口操作类只使用一次,不需要为这些类定义名称,这时可以使用匿名内部类( Anonymous Inner Class)来解决这个需求。匿名内部类的语法为:

new 父类()|接口(){
//类本体操作
}
Object obj=new Object() {
            @Override
            public String toString() {

                return "返利";
            }
        };

继承object重新定义toString方法。如果是操作接口如Some接口定义抽象方法doSome建立匿名内部类:

Some some = new Some(){
    public void doSome(){
        //执行语句
    };
};

JDK8以后接口只有一个方法可以这样:

Some some = () ->{
    //执行语句(Lambda)
}

传值调用
在一些程序语言,像是C++之类,调用方法传递自变量给参数时,可以有传值调用(Call by Value)或传参考调用( Call by Referenc)的方式。Java当中只有传值调用。传值调用也简称传值 Pass by Value),传参考调用也简称传参考( Pass by Reference)如果没有接触过具有传值调用与传参考调用项的程序语言,了解传值调用这个名词,对学习Java并没有太大意义。如果接触过C++这类可传值与传参考的语言,注意,C++这类语言中“参考”的意义,跟Java中的“参考”并不相同。

public class PassDemo {
    public static void main(String[] args) {
        Customer c1=new Customer("wanger");
        some(c1);//c1对象
        System.out.println(c1.name);

        Customer c2=new Customer("wanger");
        other(c2);//c2对象
        System.out.println(c2.name);
    }

    static private void some(Customer c) {
        c.name="zhangsan";
    }
    static private void other(Customer c) {
        c=new Customer("lisi");
    }

}
class Customer{
    String name;
    public Customer(String name) {
        this.name=name;
    }
}
/*执行结果
zhangsan
wanger
*/

在调用some()方法时传入了c1,这表示c1参考的对象也让some()方法的参数c参考(所以c1与c参考至同一个对象)。在some()方法中c.name= “zhangsan”,就是求将c参考对象的name成员指定为”zhangsan”。some方法执行结束后,c变量不存在了。下一行取得c1.name并显示。
接着看 other()方法调用时传入了c2,这表示c2参考的对象也让 other()方法的参数c参考。在 other()方法中
c= new customer(…),就是要求建立新对象,并指定给c参考,c参考至新建的对象。
some()方法执行结束后,c变量不存在了,原本c参考的对象会被JVM清除。下一行取得c2.name并显示。
这样的行为就是传值,以上示范的是传递对象给参数的情况,如果由方法中返回对象并指定给变量,也是这种行为。
这样的行为确实就是传值,而不是传参考再次强调,Java中的“参考”与C+之类语言中的“参考”,在根本上就是不同的定义,只不过刚好都叫作“参考”罢了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值