Java中内部类和静态嵌套类的主要区别是什么?设计/实现是否在选择其中一个方面发挥作用?
当前回答
不同之处在于,同样是静态的嵌套类声明可以在封闭类之外实例化。
当您有一个非静态的嵌套类声明(也称为内部类)时,Java不允许您实例化它,除非通过封闭类。从内部类创建的对象链接到从外部类创建的目标,因此内部类可以引用外部类的字段。
但是如果它是静态的,那么链接就不存在,外部字段就不能被访问(除非像其他对象一样通过普通引用),因此您可以自己实例化嵌套类。
其他回答
我已经说明了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);
}*/
//}
}
}
从Java教程:
嵌套类分为两类:静态类和非静态类。声明为静态的嵌套类简单地称为静态嵌套类。非静态嵌套类称为内部类。
使用封闭类名访问静态嵌套类:
OuterClass.StaticNestedClass
例如,要为静态嵌套类创建对象,请使用以下语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
作为内部类实例的对象存在于外部类的实例中。考虑以下类别:
class OuterClass {
...
class InnerClass {
...
}
}
InnerClass实例只能存在于OuterClass实例中,并且可以直接访问其封闭实例的方法和字段。
要实例化内部类,必须首先实例化外部类。然后,使用以下语法在外部对象中创建内部对象:
OuterClass outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
请参见:Java教程-嵌套类
为了完整性,请注意还有这样一种东西,即没有封闭实例的内部类:
class A {
int t() { return 1; }
static A a = new A() { int t() { return 2; } };
}
这里,new A(){…}是在静态上下文中定义的内部类,没有封闭实例。
内部类的实例是在创建外部类的实例时创建的。因此,内部类的成员和方法可以访问外部类的实例(对象)的成员和对象。当外部类的实例超出范围时,内部类实例也将停止存在。
静态嵌套类没有具体实例。它只是在第一次使用时加载的(就像静态方法一样)。它是一个完全独立的实体,其方法和变量不能访问外部类的实例。
静态嵌套类不与外部对象耦合,它们速度更快,并且不占用堆/堆栈内存,因为不需要创建此类的实例。因此,经验法则是尽量使用有限的范围(private>=class>=protected>=public)定义静态嵌套类,然后将其转换为内部类(通过删除“static”标识符),如果确实有必要,则放宽范围。
我认为上面的答案都没有给你一个真正的例子,说明在应用程序设计方面,嵌套类和静态嵌套类之间的区别。静态嵌套类和内部类之间的主要区别是访问外部类实例字段的能力。
让我们看看下面的两个例子。
静态嵌套类:使用静态嵌套类的一个好例子是生成器模式(https://dzone.com/articles/design-patterns-the-builder-pattern).
对于BankAccount,我们使用静态嵌套类,主要是因为
静态嵌套类实例可以在外部类之前创建。在构建器模式中,构建器是一个帮助器类,用于创建BankAccount。BankAccount.Builder仅与BankAccount关联。没有其他类与BankAccount.Builder相关,因此最好在不使用名称约定的情况下将它们组织在一起。
public class BankAccount {
private long accountNumber;
private String owner;
...
public static class Builder {
private long accountNumber;
private String owner;
...
static public Builder(long accountNumber) {
this.accountNumber = accountNumber;
}
public Builder withOwner(String owner){
this.owner = owner;
return this;
}
...
public BankAccount build(){
BankAccount account = new BankAccount();
account.accountNumber = this.accountNumber;
account.owner = this.owner;
...
return account;
}
}
}
内部类:内部类的一个常见用法是定义事件处理程序。https://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
对于MyClass,我们使用内部类,主要是因为:
内部类MyAdapter需要访问外部类成员。在示例中,MyAdapter仅与MyClass关联。没有其他类与MyAdapter相关。因此最好将它们组织在一起,而不使用名称约定
public class MyClass extends Applet {
...
someObject.addMouseListener(new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
...// Event listener implementation goes here...
...// change some outer class instance property depend on the event
}
}
}
在创建实例的情况下静态内部类是使用的引用创建的定义它的外部类的对象。这表示它具有包含实例。但是静态内部类的实例使用外部类的引用创建,而不是使用外部类对象的引用。这意味着没有包含实例。
例如:
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….
}
}
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap