【Java SE】内部类和对象的打印问题

简介: 【Java SE】内部类和对象的打印问题

🐳何为内部类:

在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。

1. public class Test {
2. class Dog{
3. 
4.     }
5. public static void main(String[] args) {
6. 
7. //        System.out.println(Student.getClasses());
8. //        Student student=new Student();
9. //        student.print();
10.     }
11. 
12. }

注意:1、定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类

2、内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件

🐳内部类的分类

根据内部类定义的位置不同,一般可以分为以下几种形式:
1. 成员内部类(普通内部类:未被static修饰的成员内部类和静态内部类:被static修饰的成员内部类)
2. 局部内部类(不谈修饰符)、匿名内部类

🐳 实例内部类

1. package Test;
2. 
3. public class OutClass {
4. private int a;
5. static int b;
6. int c;
7. 
8. public void methodA() {
9.         a = 10;
10.         System.out.println(a);
11.     }
12. 
13. public static void methodB() {
14.         System.out.println(b);
15.     }
16. 
17. // 实例内部类:未被static修饰
18. class InnerClass {
19. int c;
20. 
21. public void methodInner() {
22. // 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
23.             a = 100;
24.             b = 200;
25.             methodA();
26.             methodB();
27. // 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
28.             c = 300;
29.             System.out.println(c);
30. // 如果要访问外部类同名成员时候,必须:外部类名称.this.同名成员名字
31.             OutClass.this.c = 400;
32.             System.out.println(OutClass.this.c);
33.         }
34.     }
35. 
36. public static void main(String[] args) {
37. // 外部类:对象创建 以及 成员访问
38. OutClass outClass = new OutClass();
39.         System.out.println(outClass.a);
40.         System.out.println(OutClass.b);
41.         System.out.println(outClass.c);
42.         outClass.methodA();
43.         outClass.methodB();
44.         System.out.println("=============实例内部类的访问=============");
45. // 要访问实例内部类中成员,必须要创建实例内部类的对象
46. // 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类
47. // 创建实例内部类对象
48.         OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
49. // 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
50.         OutClass.InnerClass innerClass2 = outClass.new InnerClass();
51.         innerClass2.methodInner();
52.     }
53. }

注意:

1. 外部类中的任何成员都可以在实例内部类方法中直接访问
2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员来访问
4. 实例内部类对象必须在先有外部类对象前提下才能创建
5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

🐳 静态内部类

被static修饰的内部成员类称为静态内部类

1. package Test;
2. public class OutClass {
3. private int a;
4. static int b;
5. public void methodA(){
6.         a = 10;
7.         System.out.println(a);
8.     }
9. public static void methodB(){
10.         System.out.println(b);
11.     }
12. // 静态内部类:被static修饰的成员内部类
13. static class InnerClass{
14. public void methodInner(){
15. // 在内部类中只能访问外部类的静态成员
16. // a = 100; // 编译失败,因为a不是类成员变量
17.             b =200;
18. // methodA(); // 编译失败,因为methodB()不是类成员方法
19.             methodB();
20.         }
21.     }
22. public static void main(String[] args) {
23. // 静态内部类对象创建 & 成员访问
24.         OutClass.InnerClass innerClass = new OutClass.InnerClass();
25.         innerClass.methodInner();
26.     }
27. }

注意:

1. 局部内部类只能在所定义的方法体内部使用
2. 不能被public、static等修饰符修饰
3. 编译器也有自己独立的字节码文件,命名格式:外部类名字$内部类名字.class
4. 几乎不会使用

🐳 对象的打印

1. package Test1;
2. 
3. public class Person {
4.     String name;
5.     String gender;
6. int age;
7. 
8. public Person(String name, String gender, int age) {
9. this.name = name;
10. this.gender = gender;
11. this.age = age;
12.     }
13. 
14. public static void main(String[] args) {
15. Person person = new Person("Jim", "男", 18);
16.         System.out.println(person);//默认打印的经过哈希的地址
17.     }
18. }

如果想要默认打印对象中的属性该如何处理呢?答案:重写toString方法即可。

那么如何重写toString呢?

先右键空白处然后按下列步骤进行:

系统的是这样的:

 

修改成这样:

1. package Test1;
2. 
3. public class Person {
4.     String name;
5.     String gender;
6. int age;
7. 
8. public Person(String name, String gender, int age) {
9. this.name = name;
10. this.gender = gender;
11. this.age = age;
12.     }
13. 
14. @Override
15. public String toString() {
16. return name+"->"+gender+"->"+age;
17.     }
18. 
19. public static void main(String[] args) {
20. Person person = new Person("Jim", "男", 18);
21.         System.out.println(person);//默认打印的经过哈希的地址
22.     }
23. 
24. }


相关文章
|
17天前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
21天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
42 17
|
20天前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
29天前
|
存储 Java 数据管理
Java零基础-Java对象详解
【10月更文挑战第7天】Java零基础教学篇,手把手实践教学!
24 6
|
1月前
|
Oracle Java 关系型数据库
重新定义 Java 对象相等性
本文探讨了Java中的对象相等性问题,包括自反性、对称性、传递性和一致性等原则,并通过LaptopCharger类的例子展示了引用相等与内容相等的区别。文章还介绍了如何通过重写`equals`方法和使用`Comparator`接口来实现更复杂的相等度量,以满足特定的业务需求。
20 3
|
1月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
1月前
|
存储 Java 数据管理
Java零基础-Java对象详解
【10月更文挑战第3天】Java零基础教学篇,手把手实践教学!
16 1
|
1月前
|
Java 数据安全/隐私保护
java类和对象
java类和对象
25 5
|
20天前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
18 0
|
1月前
|
存储 前端开发 Java
你还没有对象吗?java带你创建一个吧
你还没有对象吗?java带你创建一个吧
12 0