一、匿名对象
Java中的匿名对象指的是在创建对象的时候只有创建对象的语句,但是没有创建出来的对象的地址赋值给某个变量,这样的对象叫做匿名对象。
例如:
有如下的一个Person类
public class Person{
//姓名
private String name;
//提供getter setter方法
public String getName(){
return name;
}
public String setName(String name){
return this.name = name;
}
}
public static void main(String[] args){
//创建人类型的普通对象
Person p = new Person();
//创建人类型的匿名对象
new Person();
}
匿名对象的特点:
(1)创建出来的对象可以直接使用,不需要对其进行赋值;
(2)每一次想要使用匿名对象都必须重新创建一次,因为匿名对象没有变量可以直接引用;
(3)匿名对象既可以在方法中当作实际传入的参数,也可以变成方法声明时的一个返回值。
例如:
//想使用匿名对象就要创建一次
new Person().setName("张三");
//方法中实际传入的参数
public class RandomUtil{
public static int RandomTest(Random random){
int num = random.nextInt();
return num;
}
//测试类
public class Test{
public static void main(String[] args){
int n = RandomUtil.RandomTest(new Random());
}
}
//作为方法的返回值
public static Person getInstance(){
return new Person();
}
二、匿名内部类
1、内部类
内部类就是声明在外部类里面的类,而这个内部类的外面的类就叫外部类,内部类和外部类是一个相对的概念。
内部类又分为成员内部类和局部内部类。
(1)成员内部类
成员内部类就是声明在外部类的成员位置,成员内部类又有静态成员内部类和非静态成员内部类。
1)静态成员内部类
静态成员内部类就是用 static 关键字修饰的类,它是在外部类的成员位置。
静态成员内部类的访问方式:如果想要访问内部类的方法,就得先创建一个内部类的实例对象,静态成员内部类是用 static 关键字修饰并且位于外部类的成员位置,它是属于外部类的,而不是外部类的某个具体实例对象,因此在访问他的时候可以直接通过外部类来创建。
例如:
有两个类,一个是Person类,一个是Chinese类
public class Person{
//内部类为Chinese类
public static class Chinese{
//内部类的一个方法
pubilc void characteristic(){
System.out.println("中国人最勤劳!");
}
}
//外部类的一个方法
pubilc void character(){
System.out.println("我们是人类!");
}
}
//测试类
public class Test{
public static void main(String[] args){
//创建一个Person类的实例对象person
Person person = new Person();
//创建Person类中的内部类对象Chinese类对象
Person.Chinese chinese = new Person.Chinese();
//调用外部类的方法
person.character();
//调用内部类的方法
chinese.characteristic();
}
}
2)非静态成员内部类
非静态成员内部类就是不使用 static 关键字修饰的类,它是在外部类的成员位置。
非静态成员内部类的访问方式:如果想要访问内部类的方法,就得先创建一个内部类的实例对象,对于非静态成员内部类他没有使用 static 关键字修饰,它是属于外部类的实例对象,因此在访问他的时候可以直接通过外部类的实例对象来创建。
外部类名.非静态成员内部类名 变量名 = new 外部类名().new 非静态成员内部类名();
public class Person{
public class Chinese{
public void use(){
System.out.println("中国人吃饭用筷子!");
}
}
public void use1(){
System.out.println("外国人吃饭不用筷子!");
}
}
//测试类
public class Test{
public static void main(String[] args){
//创建一个外部类实例对象
Person person = new Person();
//创建外部类Person的内部类Chinese实例对象
Person.Chinese chinese = new Person().new Chinese();
//调用方法
person.use1();
chinese.use();
}
}
(2)局部内部类
定义在成员方法中的局部位置,属于方法。
局部内部类的方法是定义在外部类的成员方法中的,因此要调用访问局部内部类的方法必须调用该
内部类所在的成员方法,然后在外部类的成员方法创建局部内部类的对象,对局部内部类的方法进
行调用。
例如:
public class Person{
//Person 类的成员方法
public void live(){
//Person类的局部内部类
class Heart{
public void work(){
System.out.println("心跳!");
}
}
//在局部内部类所在的方法中创建局部内部类对象,并调用局部内部类的方法
new Heart().work();
}
}
//测试类
//测试
public class Test {
public static void main(String[] args) {
//创建外部类 Person 的实例对象
Person person = new Person();
//通过外部类实例对象 person 调用局部内部类所在的方法 live()
person.live();
}
}
2、匿名内部类
我们可以知道,接口和抽象类是不能够直接创建对象的,只能通过接口的实现类或者抽象类的非抽象子类进行实例化操作,但是很多时候,一个抽象类的非抽象子类或者接口的实现类我们只用了一次,如果这个时候专门去创建一个接口的实现类或者抽象类的非抽象子类就会显得麻烦或者说多余,这个时候,就可以使用匿名内部类对其进行实例化操作。
例如:
//定义一个接口
public interface Fly{
void fly();
}
//测试类演示代码
public class test{
public static void main(String args[]){
//使用匿名内部类创建Fly接口类型实例对象
Fly fly1 = new Fly(){
@override
public void fly(){
System.out.println("I am flying");
}
}
fly1.fly();
}
}
匿名内部类的注意点:
(1)匿名内部类的对象只能有一个,就是在定义完匿名内部类之后就创建的;
(2)匿名内部类可以有独有的方法,根据多态的使用规则,匿名内部类类型的对象是由父类类型的变量去引用的,根据多态子父类中存在相同的方法时,能够访问哪些方法是由变量的类型决定可以得到,匿名内部类中的独有方法是无法通过父类类型的变量去调用的,如果一定要访问,那就需要把匿名内部类对象也定义成一个匿名对象并且不使用父类类型的变量去引用。
三、代码块
1、局部代码块
局部代码块是在方法或者(if、for、while等)语句中的花括号{ }中的代码,它里面的变量作用域只能在花括号内部有效,离开花括号就失效。
2、构造代码块
构造代码块是定义在类中的成员位置,方法之外,并且不使用 static 关键字修饰的代码块。
特点:
(1)创建对象的时候,优先于构造方法执行,因此可以用来对对象进行初始化操作;
(2)每创建一个对象,构造代码块就会执行一次;
(3)如果一个类中,有多个构造代码块的时候,这些构造代码块都会执行一次,并且执行的顺序就是定义的顺序,而且总是优先于构造方法执行;
(4)对于构造代码块而言可以定义在任意的成员位置,与成员变量,成员方法呵呵构造方法之间是不区分先后顺序的。
3、静态代码块
静态代码块是定义在类中的成员位置,方法之外,并且使用 static 关键字修饰的代码块。
特点:
(1)静态代码块是优先于构造代码块执行的,并且是以类以任何一种形式第一次加载的时候执行;
(2)静态代码块是属于类的,因此我们可以使用静态代码块对类进行初始化操作,例如给静态成员变量赋值,但是不能给非静态成员变量赋值;
(3)静态代码块是在类以任何一种形式第一次使用时执行,因此后面不管类进行多少次方法的调用或者说创建多少个对象,静态代码块都只执行一次。