不定长度自变量 在调用方法时,若方法的自变量个数事先没法决定该如何处理,例如 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+之类语言中的“参考”,在根本上就是不一样的定义,只不过恰好都叫做“参考”罢了。