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

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

Sys tem. out. printf("&d",10)i
 System. out. printf("%d%d", 10, 20);
 system. out. printf("%d %d %d", 10, 20, 30);
复制代码

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

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

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

System. out. printin (sum(1, 2))
 System. out. Println( sum(1, 2, 3))
 Sys tem. out. println (sum(1, 2, 3, 4))
复制代码

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

out.println(
 thtool. sum(new int[] (1, 2, 3)
)
复制代码

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

public void some(int argl, int arg2, int... varargs){
 }
复制代码

如下方式是不合法声明:this

public void some(Int... varargs, int argl, int arg2){}
复制代码

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

public void some(Other... others){}
复制代码

匿名内部类 能够在类中再定义类,这称为内部类。设计

class Some{
	class Other{
	}
}
复制代码

虽然实际应用上不多看到接下来的写法,不过要使用Some中的 other类必须先创建some实例code

Some s=new Some;
Some.Other o = new s.new otner();
复制代码

内部类也能够用public、 protected或 private声明。 内部类自己能够存取外部类的成员,一般非静态内部类会声明为 private,这类内部类是辅助类中某些操做而设计,外部不用知道内部类的存在。 内部类也能够声明为 static。例如:对象

class Some{
	static class Other{
	}
}
复制代码

一个被声明为 static的内部类,一般是将部类看成名称空间。能够这样创建类实例: 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+之类语言中的“参考”,在根本上就是不一样的定义,只不过恰好都叫做“参考”罢了。

相关文章
相关标签/搜索