💁 个人主页:黄小黄的博客主页
❤️ 支持我:👍 点赞 🌷 收藏 🤘关注
🎏 格言:立志做一个有思想的程序员 🌟
📫 作者介绍:本人本科软件工程在读,博客将主要分享JavaSE、JavaEE、MySQL、SpringBoot、算法等知识。专栏内容长期更新,如有错误,欢迎评论区或者私信指正!感谢大家的支持~~~
本篇主要学习内容及目标:
- ⭐️ 了解代码块的基本概念与用途;
- ⭐️ 掌握代码块的使用方法;
- ⭐️ 掌握静态与非静态代码块的区别;
- ⭐️ 理解并掌握在一个类中的代码块与成员的调用机制;
- ⭐️ 理解并掌握在多个类中的代码块与成员的调用机制;
文章目录
✈️ 代码块又称初始化块,属于类中的成员(属于类中的一部分),类似于方法,将逻辑语句封装在方法体中,通过{ }包围起来。但是,它和方法不同,它没有方法名,没有返回值也没有参数,只有方法体。最重要的一点是,代码块不需要通过对象或者类显示调用,而是加载类时,或者创建对象时隐式调用。
🍑 代码块的基本语法如下:
【修饰符】{
方法体
}; // 分号可以不写
🅰️ 说明:修饰符可不写,写上只可为 static,前者为普通代码块,后者为静态代码块。 分号可写可不写,依据编程者的使用习惯而定。
😦 相信不少小伙伴和博主一样,有这样的疑惑:既然代码块没有返回值没有参数,难道方法不够用吗,为何偏偏多此一举?
我们可以试想一个这样的场景,就拿我们熟悉的游戏来说——王者荣耀。当你选定英雄后,系统会进入游戏加载动画,最后开局播报语音:“欢迎来到王者荣耀,全军出击!”我们用最朴素的方法来模拟一下王者荣耀,来看代码:
public class KingGame {
public static void main(String[] args) {
Hero h1 = new Hero("伽罗", "射手");
Hero h2 = new Hero("花木兰", "战士");
Hero h3 = new Hero("李白", "刺客");
h1.startGame();
h2.startGame();
h3.startGame();
}
}
class Hero{
private String name; // 英雄姓名
private String job; // 英雄职位
public Hero(String name, String job) {
this.name = name;
this.job = job;
}
// 开始游戏
public void startGame(){
System.out.println("进入游戏加载动画~~~");
System.out.println("欢迎来到王者荣耀, 全军出击!");
}
}
在代码中,模拟了三个英雄进入游戏的进程,运行结果为:
进入游戏加载动画~~~
欢迎来到王者荣耀, 全军出击!
进入游戏加载动画~~~
欢迎来到王者荣耀, 全军出击!
进入游戏加载动画~~~
欢迎来到王者荣耀, 全军出击!
但是,我们发现,每个英雄进入游戏的时候都是弹出这两句话。还需要我们在主方法去特意调用 startGame() 方法。而代码块,就是可以简化操作,帮助我们进行初始化,即我们不必显式调用方法,就可以完成进入游戏的操作:
public class KingGame {
public static void main(String[] args) {
new Hero("伽罗", "射手");
new Hero("花木兰", "战士");
new Hero("李白", "刺客");
}
}
class Hero{
private String name; // 英雄姓名
private String job; // 英雄职位
public Hero(String name, String job) {
this.name = name;
this.job = job;
}
// 开始游戏
{
System.out.println("进入游戏加载动画~~~");
System.out.println("欢迎来到王者荣耀, 全军出击!");
}
}
🍑 因此,我们对代码块的好处进行总结:
⭐️ Star 1: static 代码块也叫静态代码块,作用就是对类进行初始化,而且 随着类的加载而执行,并且只会执行一次;

🍎 实现结果:
我是A类的静态代码块!!!
⭐️ Star 2: 对于普通代码块来说,每创建一个对象就会执行一次。 在创建对象实例时,会隐式调用。 如果只是使用类的静态成员时(类名.成员名),则普通代码块不会执行;

🍎 实现结果:
我是A类的普通代码块!!!
我是A类的普通代码块!!!
我是A类的普通代码块!!!

🍎 实现结果:
静态成员
⭐️ Star 3: 类何时被加载?
⭐️ Star 4: 创建一个对象时,在一个类的调用顺序(这里不涉及继承)
🍌 示例代码:
public class CodeBlock {
public static void main(String[] args) {
new A();
new A();
}
}
class A{
// 普通成员
String message = setNormalMessage();
// 静态成员
static String name = setStaticName();
// 普通代码块
{
System.out.println("我是A类的普通代码块!!!");
}
// 静态代码块
static {
System.out.println("我是A类的静态代码块!!!");
}
// 构造方法
public A(){
System.out.println("我是A类的构造方法");
}
public static String setStaticName(){
System.out.println("setStaticName()被调用");
return "静态成员";
}
public String setNormalMessage(){
System.out.println("setNormalMessage()被调用");
return "普通成员";
}
}
🍎 实现结果:
setStaticName()被调用
我是A类的静态代码块!!!
setNormalMessage()被调用
我是A类的普通代码块!!!
我是A类的构造方法
setNormalMessage()被调用
我是A类的普通代码块!!!
我是A类的构造方法
即,在同一类中,先静态成员初始化后普通成员初始化最后调用构造方法!!!需要注意的是,静态的成员只初始化一次!!!
⭐️ Star 5: 创建一个子类对象时,在多个类的调用顺序(满足继承关系):
顺序太复杂,不容易记忆?别担心!我们了解一下构造器的隐含条件即可:
class A{
public A(){
//(1)super();
//(2)调用代码块与成员初始化
//(3)该构造器的执行
}
🍌 下面的例子中,我们让 A类 作为父类, B类 作为子类,话不多说,上代码!
public class CodeBlock {
public static void main(String[] args) {
new B();
new B();
}
}
class A{
// 静态成员
static String name = setStaticName();
// 普通代码块
{
System.out.println("我是A类的普通代码块!!!");
}
// 静态代码块
static {
System.out.println("我是A类的静态代码块!!!");
}
// 构造方法
public A(){
System.out.println("我是A类的构造方法");
}
public static String setStaticName(){
System.out.println("A 类的setStaticName()被调用");
return "静态成员";
}
public String setNormalMessage(){
System.out.println("A 类的setNormalMessage()被调用");
return "普通成员";
}
}
class B extends A{
// 静态成员
static String name = setStaticName();
// 普通代码块
{
System.out.println("我是B类的普通代码块!!!");
}
// 静态代码块
static {
System.out.println("我是B类的静态代码块!!!");
}
// 构造方法
public B(){
System.out.println("我是B类的构造方法");
}
public static String setStaticName(){
System.out.println("B 类的setStaticName()被调用");
return "静态成员";
}
public String setNormalMessage(){
System.out.println("B 类的setNormalMessage()被调用");
return "普通成员";
}
}
🍎 实现结果:
A 类的setStaticName()被调用
我是A类的静态代码块!!!
B 类的setStaticName()被调用
我是B类的静态代码块!!!
我是A类的普通代码块!!!
我是A类的构造方法
我是B类的普通代码块!!!
我是B类的构造方法
我是A类的普通代码块!!!
我是A类的构造方法
我是B类的普通代码块!!!
我是B类的构造方法
即,在多个类(满足继承关系)中,整体满足先静态成员初始化后普通成员初始化最后调用构造方法的顺序,但是在 每一部分 都满足 先父类后子类的原则! 同时,静态成员只初始化一次!
⭐️ Star 6: 静态代码块只能直接调用静态成员(静态属性和方法),普通代码块可以调用任意成员!
😗 好啦,是时候检验一下学习成果啦!请阅读以下代码,思考控制台输出结果!
🍑 question 1:
注意类先加载后使用哦!
public class Test {
public static void main(String[] args) {
System.out.println(Person.total);
System.out.println(Person.total);
}
}
class Person{
static int total;
static {
total = 99;
System.out.println("Person 静态代码块");
}
}
Person 静态代码块
99
99
🍑 question 2:
注意类之间不是继承关系!但是存在调用!!!
public class Test {
AA a1 = new AA("a1初始化");
static AA a2 = new AA("静态a2初始化");
static {
System.out.println("Test 静态代码块执行");
if(a2 == null){
System.out.println("a2 == null");
}
}
Test(){
System.out.println("Test 无参构造器");
}
public static void main(String[] args) {
new Test();
}
}
class AA{
public AA() {
System.out.println("AA 无参构造");
}
public AA(String s){
System.out.println(s);
}
}
静态a2初始化
Test 静态代码块执行
a1初始化
Test 无参构造器
😎 解析: 在该题目中,AA 与 Test并不存在继承关系。在 new Test() 时先进行 Test类 的静态成员初始化(按照静态成员的定义顺序),后进行非静态成员的初始化(普通成员与普通代码块),最后调用 Test 的无参构造器。
🌟以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞 + 关注,非常感谢 ❤️ ❤️ ❤️ !

如果有问题,欢迎私信或者评论区!
共勉:“你间歇性的努力和蒙混过日子,都是对之前努力的清零。”

如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht