Java Nested class

本文详细解析了Java内部类的概念,区分静态内部类与非静态内部类,并解释了它们与外部类之间的关系。非静态内部类可以访问外部类的成员变量和方法,但自身不能拥有静态成员。
URL : http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

网上的一些关于内部类的概念是不完整的,还是看看SUN的文档上的标准答案。
...

Like other members, a nested class can be declared static (or not). A static nested class is called just that: a static nested class. A nonstatic nested class is called an inner class.

- Nested class分为静态Static nested class 的和非静态的 inner class, 在SUN的眼里只有Nested Class!!


As with static methods and variables, which we call class methods and variables, a static nested class is associated with its enclosing class. And like class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference.

- 静态的Static nested class是不可以直接调用它的外部类enclosing class的,但是可以通过外部类的引用来调用,就像你在一个类中写了main方法一样。
...

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's instance variables and methods. Also, because an inner class is associated with an instance, it cannot define any static members itself.

-非静态类inner class 可以自由的引用外部类的属性和方法,但是它与一个实例绑定在了以其,不可以定义静态的属性、方法(这点不是很理解,可能需要看JVM的类实现)

...
class EnclosingClass {
...
class InnerClass {
...
}
}


The interesting feature about the relationship between these two classes is not that InnerClass is syntactically defined within EnclosingClass. Rather, it's that an instance of InnerClass can exist only within an instance of EnclosingClass and that it has direct access to the instance variables and methods of its enclosing instance. The next figure illustrates this idea.


-图形化的嵌入类与外部类的关系
### JavaNestedSet 的用法与实现 在 Java 和数据库交互场景下,`Nested Set Model` 是一种用于表示树形结构的有效方法。它通过两个额外的字段 `lft`(左边界)和 `rgt`(右边界),来描述节点之间的层次关系[^2]。 #### 1. 数据库表设计 为了支持 Nested Set,在数据库中通常会创建一张包含以下字段的表格: | 字段名 | 类型 | 描述 | |--------|------------|--------------------------| | id | INT | 节点唯一标识符 | | name | VARCHAR | 节点名称 | | lft | INT | 左边界的数值 | | rgt | INT | 右边界的数值 | 这些字段中的 `lft` 和 `rgt` 值定义了节点及其子节点的位置范围。父节点的 `lft` 和 `rgt` 将始终小于其所有子节点的对应值。 #### 2. 初始化 Nested Set 结构 在使用 Nested Set 模型之前,需要初始化数据并分配合适的 `lft` 和 `rgt` 值。这可以通过递归遍历树状结构完成。例如,假设有一棵树如下所示: ``` A ├── B │ ├── C │ └── D └── E ``` 对应的 `lft` 和 `rgt` 分配可以是这样的: | 名称 | lft | rgt | |------|-----|-----| | A | 1 | 10 | | B | 2 | 7 | | C | 3 | 4 | | D | 5 | 6 | | E | 8 | 9 | 这种分配方式使得查询变得非常高效。例如,要获取某个节点的所有后代,只需查找满足条件 `node.lft BETWEEN parent.lft AND parent.rgt` 的记录即可。 #### 3. 查询操作 利用 SQL 查询语句可以从数据库中快速检索所需的数据。以下是几个常见的例子: - **获取某节点的所有子孙节点** ```sql SELECT * FROM tree_table WHERE lft BETWEEN ? AND ?; ``` - **判断两节点是否存在父子关系** ```sql SELECT CASE WHEN EXISTS ( SELECT 1 FROM tree_table t1 JOIN tree_table t2 ON t1.lft < t2.lft AND t1.rgt > t2.rgt ) THEN 'true' ELSE 'false' END AS has_parent_child_relationship; ``` 这里的占位符 `?` 表示实际应用时应替换为具体的参数值[^4]。 #### 4. 更新与维护 由于修改树结构可能涉及大量更新操作,因此需谨慎处理插入、删除等动作。一般建议先锁定整个表再执行相应逻辑以保持一致性。 --- ### 示例代码:构建简单的 Nested Set 实现 下面是一个基于 Java 的简单模拟程序,展示如何手动管理嵌套集合模型。 ```java import java.util.ArrayList; import java.util.List; class Node { String name; int lft, rgt; public Node(String name, int lft, int rgt) { this.name = name; this.lft = lft; this.rgt = rgt; } } public class NestedSetExample { private static List<Node> nodes = new ArrayList<>(); public static void main(String[] args) { buildTree(); printNodes(); System.out.println("\nQuerying descendants of node A:"); queryDescendants("A"); } private static void buildTree() { addNodeWithChildren("A", 1, 10); addNodeWithChildren("B", 2, 7); addLeafNode("C", 3, 4); addLeafNode("D", 5, 6); addLeafNode("E", 8, 9); } private static void addNodeWithChildren(String name, int lft, int rgt) { nodes.add(new Node(name, lft, rgt)); } private static void addLeafNode(String name, int lft, int rgt) { nodes.add(new Node(name, lft, rgt)); } private static void printNodes() { for (Node n : nodes) { System.out.printf("%s (%d-%d)%n", n.name, n.lft, n.rgt); } } private static void queryDescendants(String parentNodeName) { int parentLft = -1, parentRgt = -1; for (Node n : nodes) { if (parentNodeName.equals(n.name)) { parentLft = n.lft; parentRgt = n.rgt; break; } } if (parentLft != -1 && parentRgt != -1) { for (Node n : nodes) { if ((n.lft > parentLft && n.lft < parentRgt) || (n.rgt > parentLft && n.rgt < parentRgt)) { System.out.println("- " + n.name); } } } else { System.out.println("Parent not found."); } } } ``` 此代码片段展示了如何建立一棵小型树,并演示基本的操作流程。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值