Java内部类和静态嵌套类
Java中内部类和静态嵌套类之间的主要区别是什么?设计/实现在选择其中一个方面起作用吗?嗯。。。内部类是嵌套类。。。你是说匿名类和内部类吗 编辑:如果你实际上是指内部vs匿名。。。内部类只是在类中定义的类,例如:Java内部类和静态嵌套类,java,inner-classes,static-classes,Java,Inner Classes,Static Classes,Java中内部类和静态嵌套类之间的主要区别是什么?设计/实现在选择其中一个方面起作用吗?嗯。。。内部类是嵌套类。。。你是说匿名类和内部类吗 编辑:如果你实际上是指内部vs匿名。。。内部类只是在类中定义的类,例如: public class A { public class B { } } 鉴于匿名类是匿名定义的类的扩展,因此没有定义实际的“类”,如: public class A { } A anon = new A() { /* you could change behav
public class A {
public class B {
}
}
鉴于匿名类是匿名定义的类的扩展,因此没有定义实际的“类”,如:
public class A {
}
A anon = new A() { /* you could change behavior of A here */ };
进一步编辑:
Wikipedia在Java中,但我已经使用Java 8年了,这是我第一次听到这样的区别…更不用说没有引用来支持这一说法…底线是,内部类是在类中定义的类(静态或非静态),嵌套只是另一个术语,表示相同的意思
静态嵌套类和非静态嵌套类之间有细微的区别……基本上,非静态内部类可以隐式访问封闭类的实例字段和方法(因此它们不能在静态上下文中构造,这将是编译器错误).另一方面,静态嵌套类没有对实例字段和方法的隐式访问权,可以在静态上下文中构造。这些术语可以互换使用。如果您想真正学究化,那么可以定义“嵌套类”引用没有封闭实例的静态内部类。在代码中,您可能有如下内容:
public class Outer {
public class Inner {}
public static class Nested {}
}
但这并不是一个被广泛接受的定义。来自:
嵌套类分为两类:静态类和非静态类。声明为静态的嵌套类称为静态嵌套类。非静态嵌套类称为内部类
使用封闭类名访问静态嵌套类:
OuterClass.StaticNestedClass
例如,要为静态嵌套类创建对象,请使用以下语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
作为内部类实例的对象存在于外部类的实例中。考虑下面的类:
class OuterClass {
...
class InnerClass {
...
}
}
InnerClass的实例只能存在于OuterClass的实例中,并且可以直接访问其封闭实例的方法和字段
要实例化内部类,必须首先实例化外部类。然后,使用以下语法在外部对象中创建内部对象:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
见:
为完整起见,请注意,还有一种情况:
这里,
newa(){…}
是一个在静态上下文中定义的内部类,没有封闭实例。嵌套类是一个非常通用的术语:每个不是顶级的类都是嵌套类。
内部类是非静态嵌套类。
Joseph Darcy写了一篇很好的解释。内部类的实例是在创建外部类的实例时创建的。因此,内部类的成员和方法可以访问外部类的实例(对象)的成员和方法。当外部类的实例超出范围时,内部类实例也不再存在 静态嵌套类没有具体实例。它第一次使用时就被加载了(就像静态方法一样)。它是一个完全独立的实体,其方法和变量对外部类的实例没有任何访问权
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
静态嵌套类不与外部对象耦合,它们更快,并且不占用堆/堆栈内存,因为不需要创建此类的实例。因此,经验法则是尝试定义范围尽可能有限的静态嵌套类(private>=class>=protected>=public),然后将其转换为内部类(通过删除“static”标识符),并在必要时放宽范围。我认为上述答案中的真正区别并不明显 首先要正确使用条款:
- 嵌套类是包含在源代码级别的另一个类中的类
- 如果使用static修饰符声明它,则它是静态的
- 非静态嵌套类称为内部类。(我使用非静态嵌套类。)
如果您只想将属于局部的类保持在一起,或者如果嵌套类专用于封闭类,则可以使用静态嵌套类。静态嵌套类和其他所有类之间没有语义差异 非静态嵌套类是不同的beast。与匿名内部类类似,此类嵌套类实际上是闭包。这意味着它们捕获周围的作用域和封闭的实例,并使其可访问。也许一个例子可以说明这一点。请参见容器的此存根:
public class Container {
public class Item{
Object data;
public Container getContainer(){
return Container.this;
}
public Item(Object data) {
super();
this.data = data;
}
}
public static Item create(Object data){
// does not compile since no instance of Container is available
return new Item(data);
}
public Item createSubItem(Object data){
// compiles, since 'this' Container is available
return new Item(data);
}
}
在这种情况下,您希望具有从子项到父容器的引用。使用非静态嵌套类,这可以在不做任何工作的情况下工作。您可以使用语法Container来访问容器的封闭实例
更多核心解释如下:
如果查看编译器为(非静态)嵌套类生成的Java字节码,可能会更清楚:
// class version 49.0 (49)
// access flags 33
public class Container$Item {
// compiled from: Container.java
// access flags 1
public INNERCLASS Container$Item Container Item
// access flags 0
Object data
// access flags 4112
final Container this$0
// access flags 1
public getContainer() : Container
L0
LINENUMBER 7 L0
ALOAD 0: this
GETFIELD Container$Item.this$0 : Container
ARETURN
L1
LOCALVARIABLE this Container$Item L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 1
public <init>(Container,Object) : void
L0
LINENUMBER 12 L0
ALOAD 0: this
ALOAD 1
PUTFIELD Container$Item.this$0 : Container
L1
LINENUMBER 10 L1
ALOAD 0: this
INVOKESPECIAL Object.<init>() : void
L2
LINENUMBER 11 L2
ALOAD 0: this
ALOAD 2: data
PUTFIELD Container$Item.data : Object
RETURN
L3
LOCALVARIABLE this Container$Item L0 L3 0
LOCALVARIABLE data Object L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
}
会被编译成类似(字节码)的调用吗
为了完整起见:
匿名类是非静态嵌套类的完美示例,它没有与之关联的名称,以后无法引用。
术语:嵌套类是
分为两类:静态
而且是非静态的。嵌套类
声明为静态的,只需调用
静态嵌套类。非静态
嵌套类称为内部类
上课
outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass();
class outerclass A {
static class nestedclass B {
static int x = 10;
}
}
outerclass.nestedclass.x; i.e. System.out.prinltn( outerclass.nestedclass.x);
public static class A {} //ERROR
public class A {
public class B {
public static class C {} //ERROR
}
}
public class A {
public static class B {} //COMPILE !!!
}
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
OuterClass.InnerClass inner = new OuterClass.InnerClass();
public class OuterClass {
public static class Inner1 {
}
public class Inner2 {
}
}
OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();
OuterClass.Inner2 inner = new OuterClass().new Inner2();
OuterClass.Inner1 nestedObject = new OuterClass.Inner1();
class A
{
class B
{
// static int x; not allowed here…..
}
static class C
{
static int x; // allowed here
}
}
class Test
{
public static void main(String… str)
{
A o=new A();
A.B obj1 =o.new B();//need of inclosing instance
A.C obj2 =new A.C();
// not need of reference of object of outer class….
}
}
class OuterClass {
/* some code here...*/
class InnerClass { }
/* some code here...*/
}
class EnclosingClass {
static class Nested {
void someMethod() { System.out.println("hello SO"); }
}
}
class NonEnclosingClass {
public static void main(String[] args) {
/*instantiate the Nested class that is a static
member of the EnclosingClass class:
*/
EnclosingClass.Nested n = new EnclosingClass.Nested();
n.someMethod(); //prints out "hello"
}
}
class EnclosingClass {
static class Nested {
void anotherMethod() { System.out.println("hi again"); }
}
public static void main(String[] args) {
//access enclosed class:
Nested n = new Nested();
n.anotherMethod(); //prints out "hi again"
}
}
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
@Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
Outerclass.InnerClass innerObject = outerObject.new Innerclass();
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
class Test{
private static int x = 1;
static class A{
private static int y = 2;
public static int getZ(){
return B.z+x;
}
}
static class B{
private static int z = 3;
public static int getY(){
return A.y;
}
}
}
class TestDemo{
public static void main(String[] args){
Test t = new Test();
System.out.println(Test.A.getZ());
System.out.println(Test.B.getY());
}
}
class Test{
private int i = 10;
class A{
private int i =20;
void display(){
int i = 30;
System.out.println(i);
System.out.println(this.i);
System.out.println(Test.this.i);
}
}
}
public class OuterClass {
private String someVariable = "Non Static";
private static String anotherStaticVariable = "Static";
OuterClass(){
}
//Nested classes are static
static class StaticNestedClass{
private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable";
//can access private variables declared in the outer class
public static void getPrivateVariableofOuterClass(){
System.out.println(anotherStaticVariable);
}
}
//non static
class InnerClass{
//can access private variables of outer class
public String getPrivateNonStaticVariableOfOuterClass(){
return someVariable;
}
}
public static void accessStaticClass(){
//can access any variable declared inside the Static Nested Class
//even if it private
String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable;
System.out.println(var);
}
}
public class OuterClassTest {
public static void main(String[] args) {
//access the Static Nested Class
OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();
//test the private variable declared inside the static nested class
OuterClass.accessStaticClass();
/*
* Inner Class Test
* */
//Declaration
//first instantiate the outer class
OuterClass outerClass = new OuterClass();
//then instantiate the inner class
OuterClass.InnerClass innerClassExample = outerClass. new InnerClass();
//test the non static private variable
System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass());
}
}
public class InnerClassTest {
public static void main(String args[]) {
//creating local inner class inside method i.e. main()
class Local {
public void name() {
System.out.println("Example of Local class in Java");
}
}
//creating instance of local inner class
Local local = new Local();
local.name(); //calling method from local inner class
//Creating anonymous inner class in Java for implementing thread
Thread anonymous = new Thread(){
@Override
public void run(){
System.out.println("Anonymous class example in java");
}
};
anonymous.start();
//example of creating instance of inner class
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
inner.name(); //calling method of inner class
}
//Creating Inner class in Java
private class Inner{
public void name(){
System.out.println("Inner class example in java");
}
}
}
public class NestedStaticExample {
public static void main(String args[]){
StaticNested nested = new StaticNested();
nested.name();
}
//static nested class in java
private static class StaticNested{
public void name(){
System.out.println("static nested class example in java");
}
}
}
class Outter1 {
String OutStr;
Outter1(String str) {
OutStr = str;
}
public void NonStaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// below static attribute not permitted
// static String tempStatic1 = "static";
// below static with final attribute not permitted
// static final String tempStatic1 = "ashish";
// synchronized keyword is not permitted below
class localInnerNonStatic1 {
synchronized public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
public static void StaticMethod(String st) {
String temp1 = "ashish";
final String tempFinal1 = "ashish";
// static attribute not permitted below
//static String tempStatic1 = "static";
// static with final attribute not permitted below
// static final String tempStatic1 = "ashish";
class localInnerNonStatic1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// static method with final not permitted
public static void innerStaticMethod(String str11) {
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
}
// static class not permitted below
// static class localInnerStatic1 { }
}
// synchronized keyword is not permitted
static class inner1 {
static String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
public void innerMethod(String str11) {
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
public static void innerStaticMethod(String str11) {
// error in below step
str11 = temp1 +" india";
//str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
//}
}
//synchronized keyword is not permitted below
class innerNonStatic1 {
//This is important we have to keep final with static modifier in non
// static innerclass below
static final String temp1 = "ashish";
String tempNonStatic = "ashish";
// class localInner1 {
synchronized public void innerMethod(String str11) {
tempNonStatic = tempNonStatic +" ...";
str11 = temp1 +" sharma";
str11 = str11+ tempNonStatic +" sharma";
System.out.println("innerMethod ===> "+str11);
}
/*
// error in below step
public static void innerStaticMethod(String str11) {
// error in below step
// str11 = tempNonStatic +" india";
str11 = temp1 +" india";
System.out.println("innerMethod ===> "+str11);
}*/
//}
}
}
class OuterClass {
...
class NestedClass {
...
}
}
OuterClass.StaticNestedClass nestedObject =
new OuterClass.StaticNestedClass();
OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
public class Bank {
// maximum limit as per current bank policy
// is subject to change
private int maxLimit = 7000;
// ------- PUBLIC METHODS ---------
public CreditCard issueCard(
final String firstName,
final String lastName
) {
final String number = this.generateNumber();
final int expiryDate = this.generateExpiryDate();
final int CVV = this.generateCVV();
return new CreditCard(firstName, lastName, number, expiryDate, CVV);
}
public boolean setLimit(
final CreditCard creditCard,
final int limit
) {
if (limit <= this.maxLimit) { // check against current bank policy limit
creditCard.setLimit(limit); // access private method Bank.CreditCard.setLimit(int)
return true;
}
return false;
}
// ------- PRIVATE METHODS ---------
private String generateNumber() {
return "1234-5678-9101-1123"; // the numbers should be unique for each card
}
private int generateExpiryDate() {
return 202405; // date is YYYY=2024, MM=05
}
private int generateCVV() {
return 123; // is in real-life less predictable
}
// ------- PUBLIC STATIC NESTED CLASS ---------
public static final class CreditCard {
private final String firstName;
private final String lastName;
private final String number;
private final int expiryDate;
private final int CVV;
private int balance;
private int limit = 100; // default limit
// the constructor is final but is accessible from outer class
private CreditCard(
final String firstName,
final String lastName,
final String number,
final int expiryDate,
final int CVV
) {
this.firstName = firstName;
this.lastName = lastName;
this.number = number;
this.expiryDate = expiryDate;
this.CVV = CVV;
}
// ------- PUBLIC METHODS ---------
public String getFirstName() {
return this.firstName;
}
public String getLastName() {
return this.lastName;
}
public String getNumber() {
return this.number;
}
public int getExpiryDate() {
return this.expiryDate;
}
// returns true if financial transaction is successful
// otherwise false
public boolean charge(final int amount) {
final int newBalance = this.balance - amount;
if (newBalance < -this.limit) {
return false;
}
this.balance = newBalance;
return true;
}
// ------- PRIVATE METHODS ---------
private int getCVV() {
return this.CVV;
}
private int getBalance() {
return this.balance;
}
private void setBalance(final int balance) {
this.balance = balance;
}
private int getLimit() {
return limit;
}
private void setLimit(final int limit) {
this.limit = limit;
}
}
}