精华内容
下载资源
问答
  • java中匿名内部类构造方法调用

    千次阅读 2013-11-28 21:48:51
    java中匿名内部类构造方法调用
    展开全文
  • JAVA匿名内部类构造方法

    千次阅读 2013-10-08 16:10:44
    与人讨论匿名内部类构造方法问题,自己写代码看看原理到底是什么样子的。因为是匿名的,所以就无从创建一个同名的构造方法了。但是可以直接调用父类的构造方法。测试代码如下:   Java代码   ...
    与人讨论匿名内部类的构造方法问题,自己写代码看看原理到底是什么样子的。因为类是匿名的,所以就无从创建一个同名的构造方法了。但是可以直接调用父类的构造方法。测试代码如下:
    

     

    Java代码 复制代码 收藏代码
    1. package testtest;   
    2.   
    3. public class Main {   
    4.   
    5.     public static void main(String[] args) {   
    6.         InnerTest inner = new InnerTest();   
    7.         Test t = inner.get(3);   
    8.         System.out.println(t.getI());   
    9.     }   
    10. }   
    11.   
    12. class Test {   
    13.   
    14.     private int i;   
    15.   
    16.     public Test(int i) {   
    17.         this.i = i;   
    18.     }   
    19.   
    20.     public int getI() {   
    21.         return i;   
    22.     }   
    23. }   
    24.   
    25. class InnerTest {   
    26.   
    27.     public Test get(int x) {   
    28.         return new Test(x) {   
    29.   
    30.             @Override  
    31.             public int getI() {   
    32.                 return super.getI() * 10;   
    33.             }   
    34.         };   
    35.     }   
    36. }  
    package testtest;
    
    public class Main {
    
        public static void main(String[] args) {
            InnerTest inner = new InnerTest();
            Test t = inner.get(3);
            System.out.println(t.getI());
        }
    }
    
    class Test {
    
        private int i;
    
        public Test(int i) {
            this.i = i;
        }
    
        public int getI() {
            return i;
        }
    }
    
    class InnerTest {
    
        public Test get(int x) {
            return new Test(x) {
    
                @Override
                public int getI() {
                    return super.getI() * 10;
                }
            };
        }
    }

    编译之后得到4个class文件:Test.class,InnerTest.class,InnerTest$1.class以及Main.class。容易看出来,Main.class是测试类的class文件,Test.class是超类Test的class文件,InnerTest.class是InnerTest 的class文件,最值得关注的就是匿名内部类的class文件InnerTest$1.class。

    首先javap -c InnerTest$1

     

    Java代码 复制代码 收藏代码
    1. Compiled from "Main.java"  
    2. class testtest.InnerTest$1 extends testtest.Test{   
    3. final testtest.InnerTest this$0;   
    4.   
    5. testtest.InnerTest$1(testtest.InnerTest, int);   
    6.   Code:   
    7.    0:   aload_0   
    8.    1:   aload_1   
    9.    2:   putfield    #1//Field this$0:Ltesttest/InnerTest;   
    10.    5:   aload_0   
    11.    6:   iload_2   
    12.    7:   invokespecial   #2//Method testtest/Test."<init>〈init〉":(I)V   
    13.    10:  return  
    14.   
    15. public int getI();   
    16.   Code:   
    17.    0:   aload_0   
    18.    1:   invokespecial   #3//Method testtest/Test.getI:()I   
    19.    4:   bipush  10  
    20.    6:   imul   
    21.    7:   ireturn   
    22.   
    23. }   
    24.   
    25. </init>  
    Compiled from "Main.java"
    class testtest.InnerTest$1 extends testtest.Test{
    final testtest.InnerTest this$0;
    
    testtest.InnerTest$1(testtest.InnerTest, int);
      Code:
       0:	aload_0
       1:	aload_1
       2:	putfield	#1; //Field this$0:Ltesttest/InnerTest;
       5:	aload_0
       6:	iload_2
       7:	invokespecial	#2; //Method testtest/Test."<init>〈init〉":(I)V
       10:	return
    
    public int getI();
      Code:
       0:	aload_0
       1:	invokespecial	#3; //Method testtest/Test.getI:()I
       4:	bipush	10
       6:	imul
       7:	ireturn
    
    }
    
    </init>

    很明显,虽然我们看来是匿名内部类,但编译的时候给这个类指定了名字

    InnerTest$1,而且看出来是继承自Test:

    Java代码 复制代码 收藏代码
    1. class testtest.InnerTest$1 extends testtest.Test  
    class testtest.InnerTest$1 extends testtest.Test

    而且在这个类有构造方法: 

    Java代码 复制代码 收藏代码
    1. testtest.InnerTest$1(testtest.InnerTest, int);  
    testtest.InnerTest$1(testtest.InnerTest, int);
    

    这里也很容易理解,两个参数,一个是匿名内部类的外部类引用直接传了进来,这也是我们能在内部类中直接访问外部类成员的实现原理。另外一个就是int类型的参数了。也就是说其实编译器自动的给我们添加了带参数的构造方法。继续往下看: 
    7: invokespecial #2; //Method testtest/Test."<init>":(I)V
    这就是调用父类的构造方法了 。
    接下来 ,我们 只要看 InnerTest中 get方法 的 实现就可以了 :

    Csharp代码 复制代码 收藏代码
    1. Compiled from "Main.java"  
    2. class testtest.InnerTest extends java.lang.Object{   
    3. testtest.InnerTest();   
    4.   Code:   
    5.    0:   aload_0   
    6.    1:   invokespecial   #1; //Method java/lang/Object."<init>〈init〉":()V   
    7.    4:   return  
    8.   
    9. public testtest.Test get(int);   
    10.   Code:   
    11.    0:   new #2; //class testtest/InnerTest$1   
    12.    3:   dup   
    13.    4:   aload_0   
    14.    5:   iload_1   
    15.    6:   invokespecial   #3; //Method testtest/InnerTest$1."<init>〈init〉":(Ltesttest/InnerTest;I)V   
    16.    9:   areturn   
    17.   
    18. }   
    19. </init></init><PRE></PRE>  
    Compiled from "Main.java"
    class testtest.InnerTest extends java.lang.Object{
    testtest.InnerTest();
      Code:
       0:	aload_0
       1:	invokespecial	#1; //Method java/lang/Object."<init>〈init〉":()V
       4:	return
    
    public testtest.Test get(int);
      Code:
       0:	new	#2; //class testtest/InnerTest$1
       3:	dup
       4:	aload_0
       5:	iload_1
       6:	invokespecial	#3; //Method testtest/InnerTest$1."<init>〈init〉":(Ltesttest/InnerTest;I)V
       9:	areturn
    
    }
    </init></init>
    
    


    到这里一切都清楚了,InnerTest中对待匿名内部类和对待普通类一样,

    先是

    Csharp代码 复制代码 收藏代码
    1. 0:  new #2; //class testtest/InnerTest$1  
    0:	new	#2; //class testtest/InnerTest$1

    然后调用其构造方法:

    Java代码 复制代码 收藏代码
    1. 6: invokespecial #3//Method testtest/InnerTest$1."〈init〉":(Ltesttest/InnerTest;I)V<PRE></PRE>  
    6: invokespecial #3; //Method testtest/InnerTest$1."〈init〉":(Ltesttest/InnerTest;I)V
    
    


    <init></init><init>OK,一切都清楚了 。<br></init>

    展开全文
  • java匿名内部类什么是匿名内部类匿名内部类的使用场景?匿名内部类如何创建?匿名内部类的实现和使用例1(实现接口)例2(继承) 什么是匿名内部类匿名内部类,顾名思义,就是不知道这个到底是什么名字,也...

    什么是匿名内部类?

    匿名内部类,顾名思义,就是不知道这个类到底是什么名字,也就是不知道类名。

    匿名内部类的使用场景?

    匿名内部类适合创建那种只需要使用一次的类,也就是说创建一个匿名内部类,只需要用一次即可。

    匿名内部类如何创建?

    new 类名(参数) | 实现接口()
    {
    // 匿名内部类的类体部分
    }
    从上面的定义可以看出,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或者实现一个接口。
    两个规则:
    	匿名内部类不能是抽象类。
    	匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以初始化块,可以通过初始化块来完成构造器需要完成的工作。
    

    匿名内部类的实现和使用

    例1(实现接口)

    首先,定义一个匿名类要实现的接口,代码如下

    public interface Product{
     double getPrice();
     double getName();
    

    然后,定义一个实体类,实体类定义一个方法,方法的参数为上述的接口对象,到时候会传入一个匿名类对象,这个匿名类实现了上述创建的接口,代码如下

    public class Anony{
    	public void test(Product product){
    	System.out.println("购买了一个"+product.getName()+",花掉了"+product.getPrice());
    	}
    }
    

    最后测试运行:

    pubic class Test{
    	public static void main(String[] args){
    		Anony anony=new anony();
    		// 注意,此处要传入一个匿名类对象
    		anony.test(new Product(){
    			@Override
    			public double getPrice(){
    					return 578.6;
    				}
    			@Override
    			public String getName(){
    					return "联想笔记本";
    				}
    			}
    		);
    	}
    }
    

    输出:

    购买了一个联想笔记本,花掉了578.6
    

    总结:此处匿名内部类的作用就是实现了一个接口,创建了一个实现了该接口的类的对象,然后重写了这个接口中的方法。

    例2(继承类)

    首先,定义一个匿名类需要实现的抽象类,代码如下:

    public abstract class Device{
    	private String name;
    	public abstract double  getPrice();
    	public String getName(){
    	 	return name;
    	}
    	public Device(){}
    	public Device(String name){
    		this.name=name;
    	}
    } 
    

    然后,定义一个实体类,实体类定义一个方法,方法的参数为上述的抽象类对象,到时候会传入一个匿名类对象,这个匿名类继承了上述创建的抽象类,代码如下

    public class Device{
    	public void test(Device device){
    		System.out.println("购买了一个"+device.getName()+"花费了"+device.getPrice());
    	}
    }
    
    

    最后测试运行:

    pubic class Test{
    	public static void main(String[] args){
    		Anony anony=new anony();
    		// 注意,此处要传入一个匿名类对象
    		anony.test(new Device("海尔电视机"){
    			@Override
    			public double getPrice(){
    					return 578.6;
    				}
    		);
    		Device device=new Device(){
    			@Override
    			public double getPrice(){
    				return 556.56;
    			}
    			@Override
    			public String getName(){
    				return "美的电视机";
    			}
    		};
    		annoy.test(device);
    	}
    }
    

    输出:

    购买了一个海尔电视机,花掉了578.6
    购买了一个美的电视机,花掉了556.56
    

    总结:对象匿名类中继承抽象类,对于抽象类里面的抽象方法,必须要重写,对象抽象类里面的非抽象方法,可重写也可以不重写。

    展开全文
  • 其中两层花括号含义:第一层是创建一个匿名内部类,第二层是调用匿名内部类构造方法 首先新建一个测试 public class Test { public static void main(String[] args) { new Children() { ...

    首先new SQL(){{}}代码会在mybatis(新版本)注解的动态sql中会用到

    其中两层花括号含义:第一层是创建一个匿名内部类,第二层是调用匿名内部类的构造方法(由评论区铃儿响兮琳琅提及,现做改正),内层的花括号是一个构造代码块,在实例化一个对象时会先于构造方式执行,编译时会将构造代码块移入构造方法中

    1. 首先新建一个测试类
      public class Test {
          public static void main(String[] args) {
              new Children() {
                  {
                      System.out.println("===========Children============");
                      subClass();//SubClass类subClass方法调用
                      children();//Children类children方法调用
                      System.out.println(this.getClass().getName());//当前类的类名,用getSimpleName()方法没有任何输入  Test$1
                      System.out.println(this.getClass().getSuperclass().getName());//第一级父类的类名  Children
                      System.out.println(this.getClass().getSuperclass().getSuperclass().getName());//第二级父类的类名  SubClass
                      System.out.println(this.getClass().getSuperclass().getSuperclass().getSuperclass().getName());//第三级父类的类名  Object
                      System.out.println("===========Children============");
                  }
              };
              new SubClass() {
                  {
                      System.out.println("===========SubClass============");
                      subClass();
                      System.out.println(this.getClass().getName());
                      System.out.println("===========SubClass============");
                  }
              };
          }
      }
      class Children extends SubClass {
          public Children(){
              System.out.println("Children");
          }
          public void children(){
              System.out.println("children");
          }
      }
      class SubClass{
          public SubClass(){
              System.out.println("SubClass");
          }
          public void subClass(){
              System.out.println("subClass");
          }
      }

      输出内容:
      SubClass
      Children
      ===========Children============
      subClass
      children
      com.emreditor.Test$1
      com.emreditor.Children
      com.emreditor.SubClass
      java.lang.Object
      ===========Children============
      SubClass
      ===========SubClass============
      subClass
      com.emreditor.Test$2
      ===========SubClass============
      这里和普通的类继承实例化过程没有什么区别,先静态代码,后普通代码;先父类构造方法,后子类构造方法;父类的内容执行完了之后才是子类的内容

    2. 然后离开ide工具,单独用命令javac编译一下当前类的内容
      然后会得到如下的类
      其中Test$1.class和Test$2.class是Test类中main方法中的两个匿名内部类

    3. 然后用jd-gui.exe打开Test$1.class或Test$2.class文件(ps:jd-gui.exe百度下载,也可用其他的反编译软件,也可以用命令javap -c -verbose)

    4. 打开之后文件内容是这样的(我打开的是Test$1.class文件)
       

      import java.io.PrintStream;
      
      final class Test$1
        extends Children
      {
        Test$1()
        {
          System.out.println("===========Children============");
          subClass();
          children();
          System.out.println(getClass().getName());
          System.out.println(getClass().getSuperclass().getName());
          System.out.println(getClass().getSuperclass().getSuperclass().getName());
          System.out.println(getClass().getSuperclass().getSuperclass().getSuperclass().getName());
          System.out.println("===========Children============");
        }
      }

      这个构造方法中的内容和Test类中的main方法里new Children(){{}}代码中第二层花括号中的内容是一样的;

    5. 代码new SQL(){{}}中,外层花括号是创建一个匿名内部内,内层花括号是执行匿名内部类中的构造方法(由评论区铃儿响兮琳琅提及,现做改正),内层的花括号是一个构造代码块,在实例化一个对象时会先于构造方式执行,编译时会将构造代码块移入构造方法中

    6. 加一点题外话
      new 接口(){}的方式赋值给一个接口,对接口进行实列化时是创建一个匿名内部类对接口的实现,所以需要在花括号里是实现接口中的抽象方法。

      欢迎加群:517413713 讨论

    展开全文
  • Java内部匿名内部类的用法

    万次阅读 多人点赞 2016-07-21 15:46:41
    Java内部匿名内部类的用法 【尊重原创,转载请注明出处】http://blog.csdn.net/guyuealian/article/details/51981163一、内部: (1)内部的同名方法 内部可以调用外部方法,如果内部类有同名方法...
  • 匿名内部类中的构造器问题

    千次阅读 2018-12-19 08:50:13
    今天遇到了一个题,涉及到匿名内部类构造器问题,起初想当然地认为,匿名内部类连名字都没有,怎么可能有构造器,但是一经过测试,傻眼了。原来在匿名内部类中的构造代码块充当了构造器的作用。光说无益,上代码。...
  • 使用匿名内部类构造函数

    千次阅读 2013-10-08 16:33:15
    建议39: 使用匿名类构造函数 阅读如下代码,看看是否可以编译: public static void main(String[] args) { List l1 = new ArrayList(); List l2 = new ArrayList(){}; List l3 = new ...
  • 内部类: 定义在A中的B就是内部类,B在A中的地位和其他成员相同,意思就是说可以相互调用  优点:通过内部类可以...外部对象.new 内部类构造方法 Outer.Inner in = out.new Inner(); in.play(); 方...
  •  如何new一个不在同个包中只有protected构造方法的对象呢?在讲解如何实现之前,来讲一下事情的缘由。下面将说明如何实现(这里主要讲的是如何使用匿名内部类实现)。后续描述的内容如问题请广大读者能够耐心...
  •  因为匿名内部类没有名字这个特殊性质,所以我们无从给它指定构造方法构造方法必须和类名同名,类名都没有,构造方法就无从谈起了。但是匿名内部类可以通过直接调用父类的构造方法实现初始化,当然要求父类构造...
  • 匿名内部类、lambda和方法引用其实是相通的,从匿名内部类到lambda到方法引用是一个进化的过程,是一个简化的过程,更加是一个从抽象的过程。 作用都是实现接口方法,换句话说就是实现接口;只是这个接口只有一个...
  • 内部匿名内部类

    2018-11-23 13:10:06
    内部类可以引用定义在他嵌套的外部的数据和方法,不需要将外部的对象引用传递给内部类构造方法。 使用可见性修饰符定义内部类时,遵从和应用与成员上一样的可见性规则。 可以将内部类定义为static。一个...
  • java匿名内部类和lambda(匿名方法)

    千次阅读 2019-07-28 13:05:21
    匿名内部类 内部分4种:成员内部,静态内部,局部内部匿名内部类。我们今天讨论的就是其中最常见的匿名内部类。从名称可以看出,就是没有名字的,因为没有名字,所以总归和其它普通类有一些些区别: ...
  • //匿名内部类基础应用,有关匿名内部类构造器问题 //匿名内部类是没有构造函数的,但是可以使用基类的构造函数 public class AnonymousInnerClass197 { public static void main(String []args) { pacle17 p=new ...
  • 匿名内部类

    千次阅读 2018-09-22 14:12:02
    一、匿名内部类:我看到很多人提到“匿名内部类是没有名字的”,个人觉得用陈国君主编的《Java程序设计基础(第五版)》中的 “所谓匿名内部类,是指可以利用内部创建没有名称的对象,它一步完成了声明内部和...
  • Java 匿名(匿名内部类)

    千次阅读 2020-12-25 23:41:48
    Java匿名(匿名内部类) 学习的参考博文:无恨之都 1. 初识 匿名 标准说法: 内部包括:成员、局部、匿名(匿名内部类)。 匿名概念: 匿名可以使你的代码更加简洁 (JDK8之后Lambda更简洁)。 你可以...
  • 使用匿名内部类匿名内部类的分类成员匿名内部类局部匿名内部类方法内部创建匿名内部类原理分析 匿名内部类的分类 成员匿名内部类 局部匿名内部类 方法内部创建匿名内部类 public class Animal{ public void eat(){ ...
  • 程序员你真的理解匿名内部类吗?

    千次阅读 多人点赞 2019-10-10 22:22:30
    为了加深各位对匿名内部类的印象、好奇心以及求知的渴望,咋们先来看一个程序,如果提到线程你会不会立马想到接口和继承?如果提到接口和继承你会不会立马想到匿名内部类? 开篇甜点 为了加深各位对匿名内部类的...
  • 内部详解————匿名内部类

    千次阅读 2018-05-05 13:14:29
    内部三连击: ...由于匿名内部类不利于代码的重用,因此,一般在确定此内部只会使用一次时,才会使用匿名内部类。 形式 public class OutterClass { public Runnable task() { return new Run...
  • 答:匿名内部类没有构造函数,匿名内部类的创建不是为了像我们正常创建,之后调用的,匿名内部类大多用在直接创建对象上(创建对象时可以添加自己的方法,还可以调用外面的方法,类似于多重继承),创建之后...
  • java匿名内部类

    2014-02-06 16:24:00
    java的内部可以玩出好多花样。介绍都挺多,我就不废话了。专门记一下困惑了我好半天的匿名内部类。 总结一下: 1.匿名内部类通常是为了...2.匿名内部类不能有构造方法 3.匿名内部类不能定义静态变量、方法和
  • Lambda表达式与匿名内部类

    千次阅读 2019-04-24 19:27:55
    匿名内部类适合创建那种只需要一次使用的匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该的实例,这个定义立刻消失,匿名内部类不能重复使用(一次性的) 定义匿名内部类的格式如下: new...
  • 局部内部匿名内部类,具有相同的能力和作用,但局部内部的名字在方法外是不可见的。 那么为什么我们使用局部内部而不是匿名内部类呢? * 唯一理由是:我们需要一个命名的构造器或者需要重载构造器,而匿名内部类...
  • 每个中都存在一个构造方法构造方法的主要目的是为中的属性初始化的 使用关键字 new 的时候才会调用中的构造方法 要求: 1、构造方法的名称必须与名称一致 2、构造方法的定义时没有返回值类型的声明 ...
  • 匿名内部类如何同时调用多个方法

    千次阅读 2015-12-17 17:25:25
    匿名内部类如何同时调用多个方法前几天看Java学习视频的时候,讲到匿名内部类说只可以一次调用一种方法;要调用另一种方法,只能重新再建一个匿名内部类,这样是十分浪费内存的。那么我就在想,可不可以使用匿名内部...
  • 简单谈谈java中匿名内部类构造函数

    千次阅读 2018-08-05 16:25:37
    匿名内部类虽然可以用一个初始化代码块来充当构造函数,但其构造函数还是进行了特殊的处理,它在初始化时直接调用父类的同参构造函数,然后在调用自己的代码块,例如: List l5 = new ArrayList(5){ { System.out....
  • Java匿名内部类深究

    2016-10-19 17:31:59
     首先,我们要知道,匿名内部类适合创建那种只需要一次使用的,创建匿名内部类时会立即创建一个该的实例,这个定义立即消失,匿名内部类不能重复使用。  定义匿名内部类的格式如下:  new 实现接口()|...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 103,197
精华内容 41,278
关键字:

匿名内部类有构造方法吗