类之谜总结

本文深入探讨了Java中的方法重载、静态属性与方法、类初始化、instanceof操作符及构造器调用规则等内容,帮助读者理解这些核心概念并正确运用。

1.方法重载规定

分析:

JAVA重载解析过程分为2步:

(1)根据实参选取所有可应用的。

(2)根据形参选取最精确的。(并没有使用实参)

比如:

如果fun(Object o)和fun(double[]b)都是可应用的,则double[]的每个对象都是Object类型的,因此double[]比Object更精确。

public class PuzzleDemo46{ private PuzzleDemo46(Object o){ System.out.println("Object"); } private PuzzleDemo46(double[]darr){ System.out.println("double array"); } public static void main(String args[]){ new PuzzleDemo46(null); } }

2.类中的static属性的规定

每个静态的属性都在声明他的类和所有的子类中保持一个副本。

class Cat{ private static int count = 0; public Cat(){ } public void meow(){ count++; } public static int getCount(){ return count; } } class Dog{ private static int count = 0; public Dog(){ } public void woof(){ count++; } public static int getCount(){ return count; } } public class PuzzleDemo47{ public static void main(String args[]){ Cat c[] = {new Cat(),new Cat()}; Dog d[] = {new Dog(),new Dog(),new Dog()}; for(Cat e1:c){ e1.meow(); } for(Dog d1:d){ d1.woof(); } System.out.println("Cat:" + Cat.getCount()); System.out.println("Dog:" + Dog.getCount()); } }

3.静态方法的(非多态性)

静态方法调用不是动态的,因此如果调用一个静态方法,则在编译器执行期已经确定。

比如:Person p = new Student();p.say();如果say是静态方法,则调用的是Person类的静态方法。

比如:(Person)null.say();调用的是Person.say(),null不起任何作用。

总结:调用静态方法时,必须使用类来调用,而不是用类的实例进行调用。

class Dog{ public static void bark(){ System.out.println("woof "); } } class Basenji extends Dog{ public static void bark(){ } } public class PuzzleDemo48{ public static void main(String args[]){ Dog.bark(); Basenji.bark(); } }示例2:

public class PuzzleDemo54{ public static void main(String args[]){ ((PuzzleDemo54)null).greet(); greet(); } public static void greet(){ System.out.println("Hello world!"); } }

4.类的初始化

类初始化顺序:

(1)把静态字段设置为默认值。

(2)静态字段初始器按照其在源代码中出现顺序执行,比如static属性、final static属性、static语句块等,因此会出现调用还没有被初始器初始化的静态字段,尽量把属性都放在类的前面。

(3)在执行类的方法前,必须对类进行初始化。

积极初始化和延迟初始化:不要同时使用两者。

当在程序每次执行都会用到时,则使用积极初始化。

当不是每次执行都会用到时,则使用延迟初始化。

结论:类的初始化顺序显得重要时,请特别当心!

比较两个程序:

import java.util.*; public class PuzzleDemo49_2{ private static final PuzzleDemo49_2 INSTANCE = new PuzzleDemo49_2(); private final int beltSize; private final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR); private PuzzleDemo49_2(){ beltSize = CURRENT_YEAR-1930; } public int beltSize(){ return beltSize; } public static void main(String args[]){ System.out.println("Elvis wears a size " + INSTANCE.beltSize() + "belt."); } } //CURRENT_YEAR is final ,so not static
import java.util.*; public class PuzzleDemo49{ private static final PuzzleDemo49 INSTANCE = new PuzzleDemo49(); private final int beltSize; private static final int CURRENT_YEAR = Calendar.getInstance().get(Calendar.YEAR); private PuzzleDemo49(){ beltSize = CURRENT_YEAR-1930; } public int beltSize(){ return beltSize; } public static void main(String args[]){ System.out.println("Elvis wears a size " + INSTANCE.beltSize() + "belt."); } }

示例2:

class Cache{ private static boolean initialized = false; static{ initializeIfNecessary(); } private static int sum; public static int getSum(){ initializeIfNecessary(); return sum; } private static synchronized void initializeIfNecessary(){ if(!initialized){ for(int i=0;i<100;i++){ sum +=i; } initialized = true; } } } public class PuzzleDemo52{ public static void main(String args[]){ System.out.println(Cache.getSum()); } }

5.instanceof的两条规定

(1)如果instanceof的左操作数是null,则返回false;

(2)如果两个操作数的类型都是类,则instanceof的左右操作数一定是子类或父类关系;

public class PuzzleDemo50{ public static void main(String args[]){ System.out.println("null instanceof String:"+(null instanceof String)); System.out.println("int instanceof String:"+(new Integer(1) instanceof String)); //不可转换 } }

6.忠告:千万不要在构造器中调用子类覆写的方法,否则默认会调用子类覆写的方法。

public class PuzzleDemo51 extends Point{ private final String color; PuzzleDemo51(int x,int y,String color){ super(x,y); this.color = color; } protected String makeName(){ return super.makeName()+":"+color; } public static void main(String args[]){ System.out.println(new PuzzleDemo51(4,2,"Puzzle")); } } class Point{ private final int x,y; private String name; Point(int x,int y){ this.x = x; this.y = y; } protected String makeName(){ return "["+x+","+y+"]"; } public final String toString(){ name = this.makeName();//延迟初始化 return name; } }

7.局部变量声明的规定

JAVA语言规范:不允许一个局部变量声明语句作为一条语句在for、while、do循环中重复执行。

因此一个局部变量声明语句只能出现在一个语句块中。

public class PuzzleDemo55{ public static void main(String args[]){ for(int i=0;i<100;i++){ Creature creature = new Creature(); } System.out.println(Creature.numCreated()); } } class Creature{ private static long numCreated = 0; public Creature(){ synchronized(Creature.class){ numCreated++; } } public static long numCreated(){ return numCreated; } }

### 关于蓝桥杯路径算法题的解法 在蓝桥杯比赛中,路径相关的题目通常涉及图论中的搜索算法,比如广度优先搜索(BFS)、深度优先搜索(DFS),或者动态规划方法来解决最优路径问题。以下是针对此问题的一些常见解法: #### 1. 广度优先搜索 (BFS) 对于求最短路径的问题,尤其是无权图上的最短路径,BFS 是一种非常有效的解决方案。通过逐层扩展节点的方式,能够找到从起点到终点的最小步数。 ```cpp #include <iostream> #include <queue> #include <vector> using namespace std; int bfs(vector<vector<int>> &graph, int start, int end) { vector<bool> visited(graph.size(), false); queue<pair<int, int>> q; // pair<current_node, distance> q.push({start, 0}); visited[start] = true; while (!q.empty()) { auto [node, dist] = q.front(); q.pop(); if (node == end) return dist; // 找到了目标 for (auto neighbor : graph[node]) { // 遍历邻居节点 if (!visited[neighbor]) { visited[neighbor] = true; q.push({neighbor, dist + 1}); // 将邻居加入队列,并增加距离计数器 } } } return -1; // 如果无法到达,则返回-1表示不可达 } ``` 上述代码展示了如何利用 BFS 来计算两个节点之间的最短路径长度[^1]。 #### 2. 深度优先搜索 (DFS) 当需要枚举所有可能路径时,DFS 更加适用。它可以通过回溯机制探索所有的可能性,适用于寻找是否存在某种特定条件下的路径等问题。 ```cpp bool dfs(const vector<vector<int>>& graph, vector<bool>& visited, int current, int target){ if(current == target) return true; visited[current] = true; for(auto nextNode : graph[current]){ if(!visited[nextNode]){ if(dfs(graph, visited, nextNode, target)) return true; } } return false; } // 主函数调用部分省略... ``` 这段伪代码片段说明了 DFS 的基本实现方式及其递归特性。 #### 3. 动态规划 (Dynamic Programming) 如果问题是带权重边的情况或者是多阶段决策过程,则可以考虑采用 DP 方法解决问题。例如经典的旅行商问题(TSP),虽然其完全形式属于 NP 完全问题,但在规模较小的情况下仍可通过状态压缩技巧加以处理。 ```cpp const long INF = 1e9; long dp[(1<<N)][N]; for(int mask=0;mask<(1<<n);++mask){ for(int u=0;u<n;++u){ if(!(mask&(1<<u))) continue; ... } } ``` 此段未完成的代码框架给出了基于位掩码的状态转移方程雏形[^2]。 --- ### 总结 以上三种方法分别对应不同型的路径查找需求,在具体应用时需根据实际情况选择合适的策略。无论是哪种技术路线都离不开扎实的基础理论支撑以及丰富的实战经验积累。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值