Java 混淆匿名类和匿名内部类

Java 混淆匿名类和匿名内部类,java,lambda,anonymous,anonymous-class,anonymous-inner-class,Java,Lambda,Anonymous,Anonymous Class,Anonymous Inner Class,我一直在寻找如何在Java中使用lambda表达式,但却遇到了一个困惑。所以我对匿名类的理解是: public class SomeObject { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(new SomeObject()); } } 我以前见过匿名内部类这个术语,但当时我不知道什么是普通的匿名类。我看到的很多线程和视频似乎把匿名内部类称

我一直在寻找如何在Java中使用lambda表达式,但却遇到了一个困惑。所以我对匿名类的理解是:

public class SomeObject {
   public static void main(String[] args) {
    ArrayList list = new ArrayList();
    list.add(new SomeObject());
   }

}
我以前见过匿名内部类这个术语,但当时我不知道什么是普通的匿名类。我看到的很多线程和视频似乎把匿名内部类称为“匿名类”。它们是同义词吗?我对匿名内部类的理解是:

 public class Rectangle {
 private double length;
 private double width;
 private double perimeter;

    public void calculatePerimeter() {
    perimeter = (2*length) +(2*width);
   }

     public static void main(String[] args) {
       Rectangle square = new Rectangle() {
        public void calculatePerimeter() {
            perimeter = 4*length;
        }
    };
   }

  }
因此,本质上,我不必为Square编写子类,然后重写calculatePerimeter()方法,而只需创建一个一次性Square类,并在它们的。这是正确的吗

因此,匿名内部类与继承有关。但是我不明白它的用途。也许,这是因为我以前从未使用过它们,或者因为我没有太多编程经验。你能给我举个例子或者解释一下它什么时候有用吗

更新:当我将匿名内部类的代码移动到IDE时,我发现有错误;显然,“正方形”甚至没有继承矩形的字段。这难道不是更没用了吗

是否等同于:

public class Rectangle {
 private double length;
 private double width;
 private double perimeter;

    public void calculatePerimeter() {
    perimeter = (2*length) +(2*width);
   }
 }


public class Square extends Rectangle {
   @Override   
   public void calculatePerimeter() {
      perimeter = 4*getLength();
   }

  public double getLength() {
    return length;
  }



    }
所以我对匿名类的理解是:

public class SomeObject {
   public static void main(String[] args) {
    ArrayList list = new ArrayList();
    list.add(new SomeObject());
   }

}
那里没有匿名类。类
SomeObject
有一个名称。。。因此它不是匿名的。事实上,它只是一个普通(非嵌套、非内部、非匿名)Java类


我以前见过匿名内部类这个术语,但当时我不知道什么是普通的匿名类

没有所谓的“常规匿名类”。所有Java匿名类都是“内部的”

正如联合联络小组所说:

“内部类是不是显式或隐式声明为静态的嵌套类

内部类包括本地(§14.3)、匿名(§15.9.5)和非静态成员类(§8.5)。”


因此,匿名内部类与继承有关

匿名内部类确实涉及继承,但这并不是它们“内部”的原因。见上文


我指的是“list.add”(我指的是“list.add(new SomeObject());”。一直以来,我认为您添加到ArrayList的对象称为匿名类,因为我们没有命名它。);”。一直以来,我认为您添加到ArrayList的对象被称为匿名类,因为我们没有命名它

你错了。对象不是类

newsomeobject()
正在创建一个对象,而不是一个类。但这很正常。对象/实例没有名称。。。就联合联络小组而言

现在变量和字段都有了名称。。。但变量不是对象/实例或类。它们是名称和插槽之间的绑定,可以保存对对象的引用(如果类型声明允许的话)

1-除了
java.lang.Class
的实例之外。。。即使如此,从理论的角度来看,对象实际上也不是类/类型


或者它只是一个匿名对象,我把两个对象搞混了

没有。对象没有名称。所有Java对象都是“匿名的”。这不是一个有用的区别。(见上面我谈论变量的地方…)



至于您的
矩形
/
正方形
示例,它们与匿名类、内部类、嵌套类或诸如此类的内容无关。它们只是顶级类,使用普通Java继承。(我并不是说存在另一种“非普通”的继承…

第一个off-square可以访问矩形中的字段。您需要将它们标记为
受保护
私有

public class Rectangle {
    protected double length;
    protected double width;
    protected double perimeter;

    public void calculatePerimeter() {
        perimeter = (2*length) +(2*width);
    }

    public static void main(String[] args) {
        Rectangle square = new Rectangle() {
            public void calculatePerimeter() {
                perimeter = 4*length;
            }
        };
    }

}
下面是对内部类的一些很好的描述,匿名类和本地类

另外还有两种类型的内部类。可以在方法体中声明内部类。这些类称为本地类。您还可以在方法体中声明内部类,而无需命名该类。这些类称为匿名类

局部类是在块中定义的类,块是平衡大括号之间的一组零或多个语句。通常可以在方法体中找到定义的局部类

匿名类使您的代码更加简洁。它们使您能够同时声明和实例化一个类。它们与本地类类似,只是它们没有名称。如果只需要使用一次本地类,请使用它们

我认为在设计API时,匿名类的相关性就出现了。您可以创建具体的类来实现每个接口/抽象类的每一点逻辑,但这将创建大量依赖项,并且您仍然会缺少一些逻辑。匿名类的一个很好的例子是使用谓词进行过滤。喜欢

假设我有一个
列表
,我想过滤数字,删除1并返回一个新列表

public static List<Integer> filter(List<Integer> input) {
   List<Integer> rtn = new ArrayList<Integer>();
   for( Integer i : input) {
      if(i != 1) rtn.push(i);
   }
   return rtn;
} 
扩展到Lambdas,去掉
i!=1

list.stream().filter( i -> i != 1 )

为了回答后面的评论,“当我编写一个新的子类时,它继承了那些私有实例变量。在匿名内部类的情况下,它没有。”

子类从不“继承”超类的私有字段(使用JLS术语)。然而,子类可能无论如何都能够引用这些私有字段,这取决于它们所在的位置。如果子类是在超类中声明的,或者如果它们都嵌套在同一个顶级类中,子类的方法仍然可以访问该字段;假设您有一个源文件
C.java
w
interface FilterNumber {
    public boolean test(Integer i);
}

class Filter1s implements FilterNumber {
    public Filter1s(){};
    public boolean test(Integer i) { return i != 1; }
} 


public static List<Integer> filter(List<Integer> input, FilterNumber filterNumber) {
   List<Integer> rtn = new ArrayList<Integer>();
   for( Integer i : input) {
      if(filterNumber.test(i)) rtn.push(i);
   }
   return rtn;
} 

filter(list, new Filter1s());
filter(list, new FilterNumber() {
    @Override
    public boolean test(Integer i) {
        return i != 1 && i != 3 && i != 7; 
    }
});
list.stream().filter( i -> i != 1 )
class Foo1 {    
    private int bar1;
    public static class Foo2 extends Foo1 {
        public void p() {
            System.out.println(bar1);               // illegal
            System.out.println(((Foo1)this).bar1);  // works
        }
    }
}
public class Foo1 {

    private int bar1;

    public Foo1(int x) {
        bar1 = x;
    }

    public class Foo2 extends Foo1 {

        public Foo2(int x) {
            super(x * 10);
        }

        public void show() {
            System.out.println("bar1 = " + bar1);
            System.out.println("((Foo1)this).bar1 = " + ((Foo1)this).bar1);
            System.out.println("Foo1.this.bar1 = " + Foo1.this.bar1);
        }
    }
}

public class Test64 {

    public static void main(String[] args) {
        Foo1 f1 = new Foo1(5);
        Foo1.Foo2 f2 = f1.new Foo2(6);
        f2.show();
    }

}    
bar1 = 5
((Foo1)this).bar1 = 60
Foo1.this.bar1 = 5