上海实习生招聘,基础软件/嵌入式软件方向,有意留下联系方式沟通 要求: 1. 27 年毕业,会有编程考试 2. 有学校的要求,可以细聊 3. 实习工资挺好的 4. 要求实习 2 个月
做个原型页面,还是在codex 干了一版的基础上,对我的大模型对话界面进行优化调整,干了三、四轮,第一轮 设计上 出来一个毫不相干的 执行步骤的 界面,第二轮 给我直接布局干乱了,最后一轮,这个傻叉直接干白屏了,我去,我用DeepSeek 都不至于智障成这样。真是给我干麻了,无语至极。 各位佬们,你们上手试了吗? 18 个帖子 - 13 位参与者 阅读完整话题
夸克链接: https://pan.quark.cn/s/4b35a13e1c56 温馨提示:本内容仅供娱乐参考,旨在传播传统文化知识,请勿迷信。请树立科学观念,理性看待,相信科学。 1 个帖子 - 1 位参与者 阅读完整话题
各位佬友们大家好,我是一名新媒体运营零基础小白 我最近想自己做一个短视频的账号,账号的内容是记录自己和师傅钓鱼的日常,请问有没有相关行业的大佬,能帮忙指条路,应该如何去学习,在此先提前谢谢各位佬友了。 4 个帖子 - 2 位参与者 阅读完整话题
就基础编码而言,4.6 和 5.5 已经完全够用了。 高性价比的工作流程:国模搭配 5.5 完成,疑难杂症可以交给 Fable 5 来处理。 高配版的工作流程:4.8/5.5 完成,疑难杂症交给 Fable 5 来处理。 家里有矿版的工作流程:全程 Fable 5 ,一直爽。 可以看到, 就编程而言,Fable 5 并没有原子弹级别的突破,价格越来越高,账单越来越离谱,但实际的业务转化并没有提升多少。 就科研而言,Fable 5 限制重重,而且会强制“共享”你的数据。如果真有什么科研突破,只能祈祷这货能有道德了。
枚举和注解 枚举 基础知识 枚举是一组常量的集合。枚举属于一种特殊的类,里面只包含一组有限的特定的对象。 其实枚举类是可以通过传统写法自定义的,写法为: 构造器私有化 不提供set方法 在类内部预先初始化好静态的实例,并且对外暴露 代码略,直接学习如何创建真正的枚举。 使用enum关键字来代替class 直接写FALL(“秋天”,“凉爽”),效果上等价于 public static final Season FALL = new Season(“秋天”,“凉爽”); 如果有多个常量对象,使用逗号间隔即可 使用 enum 实现枚举,必须把定义的常量对象写在枚举类的最前面 使用无参构造器时,可以把括号也省略,直接写FALL,举例 FALL, SPRING, SUMMER, WINTER; public class Enum { public static void main(String[] args) { System.out.println(Season.SPRING); } } enum Season{ SPRING("春天","温暖"), SUMMER("夏天","炎热"), FALL("秋天","凉爽"), WINTER("冬天","寒冷"); private String name; private String desc; Season(String name, String desc) { this.name = name; this.desc = desc; } @Override public String toString() { return "Season{" + "name='" + name + '\'' + ", desc='" + desc + '\'' + '}'; } } .java文件可以用 Javac 编译成.class文件,.class文件也可以用 Javap 反编译成字节码文件,通过观察先编译再反编译的结果,可以看到很多隐藏的细节。 对于 Seanon 类,反编译得到的代码如下 Compiled from "Enum.java" final class hspedu.inner.enumer.Season extends java.lang.Enum<hspedu.inner.enumer.Season> { public static final hspedu.inner.enumer.Season SPRING; public static final hspedu.inner.enumer.Season SUMMER; public static final hspedu.inner.enumer.Season FALL; public static final hspedu.inner.enumer.Season WINTER; public static hspedu.inner.enumer.Season[] values(); public static hspedu.inner.enumer.Season valueOf(java.lang.String); public java.lang.String toString(); static {}; } 值得关注的细节有: 枚举类是 final 类型的,因此不可被继承 枚举类默认继承 java.lang.Enum 类,因此不可继承其他类 每一个常量都默认是 public static final 类型的 简单练习 第一题 判断语法正误 enum Gender { BOY, GIRL; } 答案: 语法没有错,相当于一个“没有属性,只含有无参构造器”的枚举类 第二题 判断输出什么 enum Gender2 { BOY, GIRL; } Gender2 boy = Gender2.BOY; Gender2 boy2 = Gender2.BOY; System.out.println(boy); System.out.println(boy2 == boy); 答案: BOY true 分析: 首先,枚举类本质也是类,所以Gender2 boy = Gender2.BOY;这种写法肯定是对的 boy相当于拿到了枚举类里的public static final常量,因此boy和boy2肯定是一样的 System.out.println(boy)相当于调用Gender2的toString方法,但是显然它没有,就去找父类的toString方法,父类是java.lang.Enum(前面有提到) Enum类的成员方法 分别是 name、ordinary、values、valueOf、compareTo方法,建议自己写一写用一用,方法的效果都写在代码里了: public class Enum { public static void main(String[] args) { Season spring = Season.SPRING; // name方法,建议优先使用toString,效果类似 System.out.println(spring.name()); System.out.println(spring); // ordinary方法,输出该枚举对象的序号,从0开始 System.out.println(spring.ordinal()); // values方法,返回所有的枚举对象 Season[] values = Season.values(); for (Season value : values) { System.out.println(value); } // valueOf方法,返回指定名称的枚举对象 Season valueOf = Season.valueOf("FALL"); System.out.println(valueOf); // compareTo方法,比较两个枚举对象,返回它们的序号之差,在这里是spring的序号 - valueOf的序号 System.out.println(spring.compareTo(valueOf)); } } enum Season{ SPRING("春天","温暖"), SUMMER("夏天","炎热"), FALL("秋天","凉爽"), WINTER("冬天","寒冷"); private String name; private String desc; Season(String name, String desc) { this.name = name; this.desc = desc; } } 简单练习2 声明 Week 枚举类,其中包含星期一至星期日的定义; MONDAY, TUESDAY, WEDNESDAY, THURSDAY,FRIDAY, SATURDAY, SUNDAY; 使用 values 返回所有的枚举数组,并遍历,要求打印值为“星期一”而不是“MONDAY” public class Enum { public static void main(String[] args) { Week[] values = Week.values(); for (Week value : values) { System.out.println(value); } } } enum Week{ MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY("星期三"), THURSDAY("星期四"), FRIDAY("星期五"), SATURDAY("星期六"), SUNDAY("星期日"); private String name; Week(String name) { this.name = name; } @Override public String toString() { return name; } Enum类的接口 Enum类本身已经有了继承关系,因此不能继承其他类 但作为一个类,它仍然可以实现接口 interface Playing { void play(); } enum Music implements Playing { HARD_ROCK, POP, CLASSIC, ROCK, JAZZ; @Override public void play() { } } 注解 最基本的修饰符 最基本的三个修饰符分别是: Override:用来限定某个方法必须重写父类的方法,只能用于方法 SuppressWarnings:抑制编译器的警告 Deprecated:用来表示某个程序元素(比如类或者方法)已经过时 Override 其实对于正确的方法重写来说,加不加这个修饰符都可以。 但如果加了的话,编译器会检查你是否有正确地重写这个方法。如果不正确的话会报错,产生编译错误。 Override的源码如下,从 @Target (ElementType.METHOD) 上可以看出,这个修饰符只能用在方法上。 @interface 修饰的类都是注解类。 @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { } 顺带一提, @Target 是修饰注解的注解,也称为元注解。 Deprecated 用 @Deprecated 修饰符修饰的元素,暗示其已经过时了,不推荐再继续使用,但其实可以使用。 @Documented @Retention(RetentionPolicy.RUNTIME) @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE}) public @interface Deprecated { String since() default ""; boolean forRemoval() default false; } 从源码可以看出,该修饰符可以修饰方法、字段、包、参数等。 该关键字一般用于 JDK 版本更迭时,给过时的方法打上标注。 SuppressWarnings 用来抑制编译器警告,在 ( ) 中可以填抑制的警告类型。 因为懒得打字,我直接把文档粘在这: 参数名称 作用描述 all 抑制所有警告。 unchecked 抑制与泛型相关的“未经检查的操作”警告,例如在使用原始类型时。 deprecation 抑制使用了 @Deprecated 标记的过时类或方法的警告。 rawtypes 抑制使用了泛型但未指定具体类型的“原始类型”警告。 unused 抑制代码中存在但未被使用的变量、方法或类的警告。 serial 抑制可序列化的类未定义 serialVersionUID 的警告。 null 抑制与空值分析相关的警告(如潜在的空指针)。 cast 抑制与强制类型转换操作相关的警告。 fallthrough 抑制在 switch 语句中缺少 break 而导致“直通”的警告。 finally 抑制 finally 块无法正常返回的警告。 boxing 抑制与自动装箱(boxing)和拆箱(unboxing)操作相关的警告。 static-access 抑制不正确的静态成员访问方式的警告。 dep-ann 抑制使用过时注解的警告。 incomplete-switch 抑制 switch 语句中未覆盖所有枚举常量的警告。 javadoc 抑制与 Javadoc 相关的警告。 synthetic-access 抑制内部类访问未优化的警告。 resource 抑制与资源(如 Closeable )使用相关的警告。 restriction 抑制使用了不建议或禁止引用的警告。 使用示例,代码如下: @SuppressWarnings({"all"}) enum Music implements Playing { HARD_ROCK, POP, CLASSIC, ROCK, JAZZ; @Override public void play() { } } @SuppressWarnings是没有对使用位置限制的,从源码中也可以看出,它没有 @Target 去限制,源码如下: @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); } 元注解 注解的注解,看源码时可能遇到,没那么重要,快速过一下。 四种元注解: Retention:指定注解的作用范围,三种值SOURCE,CLASS,RUNTIME Target:指定注解可以在哪些地方使用 Documented:指定该注解是否会在javadoc体现,即在生成文档的时候,可以看到该注解 Inherited:子类会继承父类注解 这部分我战略性跳过了,稍微不太好理解,也有点深入了。 1 个帖子 - 1 位参与者 阅读完整话题
各位佬友好! 最近一直在考虑创业开一家彩票店,但完全是零基础,已经查了很多资料,也用AI也整理了一些文档,但是没有实际开过,所以心里没底,不确定AI的回答是对是错,所以想向有经验的佬们请教一些问题,希望能得到一些指点: 前期准备阶段 开彩票店需要满足哪些硬性条件?(比如店面面积、位置要求、资金门槛等) 申请流程复杂吗?大概需要多长时间能办下来? 初期投入大概需要多少?有哪些隐性成本? 福彩和体彩有啥区别? 选址与装修 什么样的地段比较适合开彩票店?人流大的地方一定好吗? 店面装修有什么讲究?是否需要特别的设计来吸引顾客? 运营与管理 日常经营中需要注意哪些细节?(比如营业时间、服务技巧等) 如何积累和维护客户群体?有没有什么有效的营销方法? 利润空间怎么样?回本周期大概是多久? 风险与避坑 这个行业最大的风险点在哪里? 各位前辈踩过哪些坑?有什么血泪教训可以分享? 市场前景如何? 9 个帖子 - 9 位参与者 阅读完整话题
就基础编码而言,4.6 和 5.5 已经完全够用了。 高性价比的工作流程:国模搭配 5.5 完成,疑难杂症可以交给 Fable 5 来处理。 高配版的工作流程:4.8/5.5 完成,疑难杂症交给 Fable 5 来处理。 家里有矿版的工作流程:全程 Fable 5 ,一直爽。 可以看到, 就编程而言,Fable 5 并没有原子弹级别的突破,价格越来越高,账单越来越离谱,但实际的业务转化并没有提升多少。 就科研而言,Fable 5 限制重重,而且会强制“共享”你的数据。如果真有什么科研突破,只能祈祷这货能有道德了。
就基础编码而言,4.6 和 5.5 已经完全够用了。 高性价比的工作流程:国模搭配 5.5 完成,疑难杂症可以交给 Fable 5 来处理。 高配版的工作流程:4.8/5.5 完成,疑难杂症交给 Fable 5 来处理。 家里有矿版的工作流程:全程 Fable 5 ,一直爽。 可以看到, 就编程而言,Fable 5 并没有原子弹级别的突破,价格越来越高,账单越来越离谱,但实际的业务转化并没有提升多少。 就科研而言,Fable 5 限制重重,而且会强制“共享”你的数据。如果真有什么科研突破,只能祈祷这货能有道德了。
token 现在可以理解成AI的"基础语素", 大约1个token对应1.5到2个中文字, 所以1000 tokens/s换算过来差不多 一秒1500到2000个 字。普通人看文章的速度大概是一秒4到5个字,所以意思就是MiMo现在写东西比你读还快几百倍。这么看来,是真的挺夸张的 7 个帖子 - 5 位参与者 阅读完整话题
ShipAny 新版本发布了🎉,上线了三套基础模板👇 shipany-next:Agent-Native 开发框架,面向 Agent Coding 而设计,通过内置 Skills 极速开发新项目 shipany-vinext:基于 Cloudflare 官方 Vinext 框架而设计,一键部署到 Cloudflare Workers ,压缩后体积是 shipany-two 的 1/7 ,绑定 CF 全家桶,节约成本 shipany-tanstack:基于 TanStack Start 而设计,使用 Vite 构建,启动与运行速度极快,跨平台部署方便 ShipAny 老用户支付 $1.99 获得新模板。新用户通过这个链接👇 https://shipany.ai/zh/pricing?ivt=idoubi 购买 Premium 会员,输入优惠码: NEXT ,立减 $50 ShipAny 官网也基于 shipany-tanstack 完成了重构,交互体验提升不少。 ShipAny 开发文档也更新了。 ShipAny 新版本整合了流行的技术栈,主推 TanStack + Vite 生态,高性能运行,部署到 Cloudflare ,极具性价比。 ShipAny 新版本精心设计了几个 Skills ,在 Coding Agent 一键调用,对话式快速完成新项目开发。 做 AI SaaS 网站需要的基础功能,ShipAny 基本上都集成了,主打一个开箱即用,让你的 Coding Agent 无需造轮子,快速上线。 ShipAny 官方出品的基础模板,ShipAny Premium 会员可以超低价获取,主打一个仪式感,让买模板跟买咖啡一样简单。 ShipAny 用户提交了几百个案例,有一些有很大的流量,有一些赚到了钱。ShipAny 定位是一把好铲子,帮助用户去淘金。 加入 ShipAny 联盟,设置专属的邀请链接和优惠码。可自行分配额度,帮助朋友获得优惠,自己获得奖励。 我们已经进入了 Agent 主导开发的新时代,做产品变得极其简单。 一个 Agent-Native 开发框架,可以让 Agent 更快速地集成项目需要的基础能力:登录、注册、支付、积分、存储、多语言、SEO 、AI 生成、管理后台。 ShipAny 的定位,就是这样一个 Agent-Native 开发框架,通过一系列的模板覆盖常用的技术栈和业务功能,内置丰富的 Skills 让 Agent 开箱即用,帮助创作者一小时上线功能完整、可商业化的 AI 产品。 新版本,新征程。期待与 ShipAny 用户共建生态,做大做强。✌️
就基础编码而言,4.6 和 5.5 已经完全够用了。 高性价比的工作流程:国模搭配 5.5 完成,疑难杂症可以交给 Fable 5 来处理。 高配版的工作流程:4.8/5.5 完成,疑难杂症交给 Fable 5 来处理。 家里有矿版的工作流程:全程 Fable 5 ,一直爽。 可以看到, 就编程而言,Fable 5 并没有原子弹级别的突破,价格越来越高,账单越来越离谱,但实际的业务转化并没有提升多少。 就科研而言,Fable 5 限制重重,而且会强制“共享”你的数据。如果真有什么科研突破,只能祈祷这货能有道德了。
就基础编码而言,4.6 和 5.5 已经完全够用了。 高性价比的工作流程:国模搭配 5.5 完成,疑难杂症可以交给 Fable 5 来处理。 高配版的工作流程:4.8/5.5 完成,疑难杂症交给 Fable 5 来处理。 家里有矿版的工作流程:全程 Fable 5 ,一直爽。 可以看到, 就编程而言,Fable 5 并没有原子弹级别的突破,价格越来越高,账单越来越离谱,但实际的业务转化并没有提升多少。 就科研而言,Fable 5 限制重重,而且会强制“共享”你的数据。如果真有什么科研突破,只能祈祷这货能有道德了。
各位佬们好。 发这个贴主要是想给佬们分享一下我如何从萌新开始独立汉化了一个我非常喜欢却非常难汉化的传统roguelike游戏。 我是一个之前只接触过SD和Comfyui画图以及LLM大模型基础运用的小萌新。之前从来没有Codex以及CC或者基础的agent的使用经验。 然后就在前几天的openai team bug的狂潮下,机缘巧合接触到了我们社区,写了小作文加入了社区。 于是事情便一发不可收拾。 周日早上部署codex,尝试了公益api,对frogcomposband进行了代码梳理和一些简单的功能改动。 发现codex随手一脚踢死了之前让我们群很为难的mingw32位无法转到64位编译的问题。 此时我意识到codex强大的远超我的想象。 我开始尝试让codex解析硬编码,让他给我导出一份硬编码内需要翻译的文本。 我靠,codex那个迅速啊,立马给我整理完了。我很激动,感觉汉化成功就在不远处。 但是我觉得用codex来跑翻译太暴殄天物了,于是我就用我自己的gemini开始跑汉化文本,并且codex继续修改一些中文本地化会存在的问题。 周日晚上,我翻译完了高优先级的硬编码文本,大概一万两千行文本。回填完毕,不出意料游戏闪退了崩溃了。 然后啊然后啊家人们,我第一次意识到几十年前的肉鸽的代码有多垃圾!!! (先抛开C语言遇到的整形和字符型printf出错后的崩溃) 这个破烂作者。 他竟然给文本初始化的值非常小,导致汉化后字节超了,然后程序内多了几十个一遇到就会闪退的点。还有初始化时缓冲窗口太短,导致有的人初始化稍微慢点就直接崩溃 这里列举两个很抽象的。 怎么会有人写的代码是“birth 页面主动条目是 40 个,正好等于旧数组长度;”????,意思是我甚至都不需要本地化来发力,多加几条就直接崩溃吗??? 但是在codex的伟力下,我只需要狠狠蹬就可以解决这些问题。 一步步的debug,测试。 这期间我还学会了用codex建立github仓库,用gh来commit和release,还学会了给codex准备gdb让他来调试。 过程中还给游戏增加了很多qol改动,比如背景渲染改色,中英文字体分开选择等。 周一早上在工位摸鱼偷偷debug的过程中,我突然灵感来了,想着把我曾经玩过的另一个游戏《tomenet》里的种族和职业搬过来。 很顺利啊,我总结了一些信息之后codex很轻松的就写出了方案然后实现了构想(当然也有不少问题,一一解决了)。这几天正在边玩边测试。 说这么多主要其实还是想给佬们分享自己的经历。从一个一点编程也不懂,顶多知道一些AI的基础操作和部署的萌新,大概花了三天就独立(抱着codex大腿)完成了汉化和debug工作,把自己非常喜欢的游戏汉化了并分享给更多的人。 以及感谢L社区这个平台,和各位无私奉献的佬们,让我有这个机会能够把自己喜欢的游戏汉化了。 我还在b站上传了游戏介绍视频,如果佬们感兴趣可以去看看,不知道是不是不能放链接,我就放个BV号吧BV1HpE26UEfz,这是第二个实况视频,第一个视频粗略的介绍了一下游戏。 5 个帖子 - 4 位参与者 阅读完整话题
最近回到了学校,忙完了毕业的事,就一直在兜兜转转地学基础知识。之前在家待的都长毛了。突然忙起来,感觉也不错。 最近感觉自己在生活习惯上和心态上又有了一些转变,所以打算写点什么来分享一下。 想分享一下自己总结的的几个习惯。 1.输出和输入同等重要 很多人在学习时都容易犯一个错误,就是过度的追求输入,而很少输出。比如学习课程时,经常有弹幕刷“我今天学了三十课。”但你学了三十课,有没有积累三十课的笔记呢?有没有去进行三十课的实践呢?实际上二者同等重要,甚至可以说输出比输入还重要,因为输出可以倒逼输入,而长时间的输入容易给自己制造已经学会了的假象。 2.学习/输入、思考/实践/内化、输出 只有输入和输出还不够,中间的思考实践内化这一步可以防止你变成“把学到的知识逐字背诵”,而是真正带着一点理解(哪怕很少),去把知识真情实感地表达出来。 对于学技术,我建议就直接敲敲代码去实践。 有一些人生道理,不容易在生活中随时都能实践,就可以多多思考消化。 3.大量分享 把自己的想法写出来,只是输出。那既然都已经输出了,不如找合适的论坛或者社区,把自己的想法分享出来,和大家讨论,能获得一些正反馈。 2 个帖子 - 2 位参与者 阅读完整话题
想转型数字游民,以前有python java基础,现在不知道从哪里开始入手,智能合约会一点,求带 1 个帖子 - 1 位参与者 阅读完整话题
先介绍下我的背景吧,我是9本非科班跨考的某2计算机硕士。然后介绍下我的计算机背景。 我对自己的研究方向深度学习 CV 方向比较熟悉,毕竟看了快一年的论文也做了几个月实验,发了一篇水会。 编程语言学过 python,没有系统学习过 java 前后端项目的基础知识,只速成过一个 java 前后端分离的简单复试项目。目前在一家小公司智能体开发岗位打杂,自己 vibe coding 过小的智能体,对提示词、知识库、工作流、langgrah 有一点点了解。 我目前是在准备考公中,但是现在考公竞争太激烈了,担心考不上到时候工作也找不到,所以想了解下有没有对编程能力要求低的公司或者岗位? 或者有没有能速成的,学习时间不太长的学习路线,找工作机会比较多? 我个人偏向国企类的稳定的工作,如果佬有国企方面的求职经验的话,还请赐教,谢谢各位佬友了! 2 个帖子 - 2 位参与者 阅读完整话题
我的其他笔记可以查看 JAVA学习记录总贴 内部类 基础知识 内部类的类的第五大成员。 五大成员分别是:属性、方法、构造器、代码块、内部类。 定义:一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为“内部类”,在外面的类称为“外部类”,内部类最大的特点就是可以访问私有属性,并且可以体现类与类之间的包含关系。 语法 class Outer{//外部类 class Inter{//内部类 } } class OtherOuter{//外部其他类 } PS:内部类是OOP的重难点,底层源码有大量的内部类,必须要要下来这一块。 分类 定义在外部类局部位置(比如方法内) 局部内部类(有类名) 匿名内部类(无类名,重点!!!!!!!) 定义在外部类的成员位置上 成员内部类(没用static) 静态内部类(使用static) class OuterClass { //成员内部类 class MemberInnerClass {} //静态内部类 static class StaticInnerClass{} //外部方法 public void outerMethod() { //局部内部类 class LocalInnerClass {} //匿名内部类 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("匿名内部类"); } }; runnable.run(); } } 局部内部类 细节 局部内部类定义在外部类的局部位置,比如在方法中,并且有类名。(代码块中也行,但罕见) 可以直接访问外部类的所有成员,包含私有的 不能添加访问修饰符,因为局部内部类本质上就是一个局部变量,局部变量不能使用修饰符,同理它也不能,但它可以使用final,因为局部变量也可以用final,顺带一提abstract也可以。 局部内部类是可以被继承的。 作用域:仅仅作用在定义它的方法或代码块中 局部内部类想访问外部类的成员,直接访问即可 外部类想访问局部内部类的成员,可以在作用域内实例化局部内部类,但是注意,必须在定义它之后再new 外部其他类不可能访问局部内部类,这个挺好理解,因为局部内部类本质局部变量,不在它作用域内。 如果外部类和局部内部类变量重名,则会遵循就近原则,优先访问到局部内部类的变量,如果想要访问外部类的成员,则用如下语法 外部类类名.this.成员名 ,ps:顺带一提,如果你不嫌脱裤子放屁,其实 外部类类名.this.成员名 这种语法,可以在类的所有地方精确调用到本类成员 再顺带一提,其实所有内部类都可以在内部继续写内部类,这也是它复杂的原因 class OuterClass { private int n1 = 10; private void m2() {} public void m1() { class InnerClass { public void show() { // 可以直接访问外部类的所有成员,包括私有类型,包括方法 System.out.println("n1 = " + n1); m2(); } } class A extends InnerClass{ } InnerClass innerClass = new InnerClass(); } } 建议对着上面的代码,每一条细节都去自己实践一遍,看看违反了会报什么错。 匿名内部类 重点中的重点,这部分所有代码建议自己真的看完书去手敲一下,不要指望看一遍能懂,更不要单纯相信遇到的时候让AI来解释就好,没那么轻松。 特点 本质是类,底层会有独立的class字节码文件 属于内部类,定义在外部类/代码块,这类局部位置中 没有类名,其实底层是有的,但是程序员不关心,因而匿名 同时也是一个对象,类定义好的同时就已经被创建了 基本语法 new 父类/接口名(构造参数列表){ // 类体:重写父类/实现接口的抽象方法,也可以新增自定义成员 }; 基于接口的匿名内部类 class Outer04 { private int n1 = 10; public void method() { // 基于接口的匿名内部类 // 1. 需求:使用IA接口,并创建对象 // 2. 传统方法是写一个类,实现接口,创建对象,并调用方法 // 3. 但如果我们的需求是,这个类只用一次,那么定义出来就有些浪费了,所以我们可以使用匿名内部类来简化开发 // inner的编译类型是IA,而inner的运行类型是匿名内部类 /*其实这里的底层含义是 class Outer04$1 implements IA { @Override public void cry() { System.out.println("匿名内部类实现了cry方法"); } } */ // 4. jdk底层创建了匿名内部类Outer04$1,然后创建了实例,并且把地址返回给inner // 5. 匿名内部类只能使用一次,不能再次使用 IA inner = new IA(){ @Override public void cry() { System.out.println("匿名内部类实现了cry方法"); } }; inner.cry(); System.out.println(inner.getClass()); IA inner1 = new IA(){ @Override public void cry() { System.out.println("匿名内部类实现了cry方法"); } }; System.out.println(inner1.getClass()); } } interface IA { public void cry(); } 值得说的细节在注释里都已经写明了,我在此补充一点 Outer04$1 就是 JVM 自动为第一个匿名内部类分配的名字,数字表示该类在外部类中出现的顺序。 基于类的匿名内部类 class Outer04 { private int n1 = 10; public void method() { Father fa = new Father("张三"); Father fa1 = new Father("张三"){}; // 证明匿名类创建的不是Father类,而是匿名内部类 System.out.println(fa.getClass()); System.out.println(fa1.getClass()); Father fa2 = new Father("张三"){ @Override public void show() { System.out.println("匿名内部类重写show()"); } }; fa2.show(); Animal animal = new Animal() { @Override public void eat() { System.out.println("匿名内部类重写eat()"); } }; animal.eat(); } } class Father { private String name; public Father(String name) { this.name = name; } public void show() { System.out.println("show()"); } } abstract class Animal{ public abstract void eat(); } 简单总结一些要点 匿名内部类可以重写方法 父类的构造器如果有参数,则你也要提供对应参数(如果有多个构造器,那你就提供符合其中一个的就行) 基于抽象类(接口)的匿名内部类,必须实现其中所有抽象方法 一些细节 匿名内部类,既有定义一个类的特性,也有创建对象的特性,是一个凉面派 可以直接访问外部类的所有成员,包括外部私有成员 不能添加访问修饰符(直觉看上去也没办法提交orz),因为它本质是局部变量 作用域仅在定义它的方法or代码块中 外部其他类也不能访问匿名内部类,因为其本质局部变量 如果外部类和匿名内部类变量重名,则会遵循就近原则,优先访问到局部内部类的变量,如果想要访问外部类的成员,则用如下语法 外部类类名.this.成员名 匿名内部类练习 题目1:写一个基于接口的匿名内部类,并把它作为方法参数传入 public class AnonymousClass { public static void main(String[] args) { // 方式1:直接在参数位置编写匿名内部类 f1(new AA() { @Override public void show() { System.out.println("匿名类实现接口"); } }); // 方式2:先创建匿名内部类对象,再传入参数 AA aa = new AA() { @Override public void show() { System.out.println("匿名类实现接口"); } }; f1(aa); } public static void f1(AA aa){ aa.show(); } } interface AA{ void show(); } 题目2: 定义一个铃声接口 Bell,接口中包含 ring() 方法。 定义一个手机类 Cellphone,类中包含闹钟功能方法 alarmclock(Bell bell),方法的参数类型为 Bell。 测试手机类的闹钟功能:通过匿名内部类创建 Bell 接口的实现对象,作为参数传入 alarmclock 方法,调用 ring() 方法时打印:懒猪起床了。 再传入另一个匿名内部类对象,调用 ring() 方法时打印:小伙伴上课了。 public class AnonymousClass { public static void main(String[] args) { new Cellphone().alarmclock(new Bell() { @Override public void ring() { System.out.println("懒猪起床了"); } }); new Cellphone().alarmclock(new Bell() { @Override public void ring() { System.out.println("小伙伴上课了"); } }); } } interface Bell { void ring(); } class Cellphone { public void alarmclock(Bell bell){ bell.ring(); } } 重点:一定要写一写感受一下,这部分涉及:多态、继承、动态绑定、内部类,多个知识点混杂在一起,需要认真练习 成员内部类 成员内部类定义在外部类的成员位置,并且没有static修饰 可以访问外部类的所有成员 可以添加任意的修饰符,因为其地位相当于一个成员 成员内部类的作用域和外部类的其他成员一样,都是整个类体。 成员内部类可以调用外部类的所有成员,包括私有。 外部类可以访问成员内部类的所有成员,包括私有成员,不过,必须要创建实例才能访问。 外部其他类想要访问成员内部类,有两种方法,分别标注在代码里了 如果外部类和内部类成员同名,则内部类访问时采取就近原则,如果一定要访问外部类的同名成员,则采用 外部类.this.成员名 的方式 public class AnonymousClass { public static void main(String[] args) { // 外部其他类访问成员内部类的两种方式 // 方式一 通过外部类对象访问成员内部类对象,下面的两种写法本质上是等价的 Outer.Inner inner = new Outer().new Inner(); // 写法1 Outer outer = new Outer(); // 写法2 Outer.Inner inner1 = outer.new Inner(); // 方式二 在外部类中编写一个写法,返回成员内部类对象 Outer.Inner inner2 = outer.getInner(); } } class Outer{ private int n1 = 10; private String name = "张三"; public Inner getInner(){ return new Inner(); } // 成员内部类 // 成员内部类是定义在外部类的成员位置上 public class Inner{ private int n2 = 20; public void say(){ System.out.println("n1 = " + n1 + " name = " + name); } } public void show(){ Inner inner = new Inner(); // 即使是类内部的私有成员也可以被访问,因为本质上它也是类的一部分。 System.out.println(inner.n2); } } 静态内部类 静态内部类定义在外部类的成员位置,并且有 static 修饰符。 静态内部类可以直接访问外部类的所有静态成员(包括私有的),但是不能直接访问非静态成员;可以访问本类的所有成员,不管是静态还是非静态 解释: 静态内部类是外部类的一部分,因而可以访问外部类的所有静态成员。 对于外部类的非静态成员,可以在静态内部类中实例化,然后访问。 可以添加任意访问修饰符,因为它的地位就是一个成员 作用域和其他的成员一样,是整个类体内部。 静态内部类可以在不依赖外部类的前提下被实例化 外部其他类访问静态内部类、静态内部类访问外部类、外部类访问静态内部类的逻辑都写在了代码里,如下所示 外部类和静态内部类成员重名时,静态内部类如果想要访问,则默认就近原则,如果想要访问外部类的同名成员,则需要 外部类名.成员 P.S. 内部类可以是静态的,但是顶层类不能是静态的。 public class AnonymousClass { public static void main(String[] args) { // 展示外部其它类访问静态内部类的方式 // 方式1,直接new Outer.Inner inner = new Outer.Inner(); inner.sayHello(); // 方式2,编写一个方法,返回静态内部类的实例。 Outer.Inner inner1 = new Outer().getInnerInstance("java"); inner1.sayHello(); // 方式2的补充,可以在外部类中写静态方法,返回静态内部类的实例,没有本质区别 Outer.Inner inner2 = Outer.getInnerInstance_("HSP"); inner2.sayHello(); } } class Outer { private int n1 = 10; private static int n2 = 20; // 静态内部类 public static class Inner { private String name; private static int count = 0; private static int n2 = 30; // 静态内部类可以有构造器 Inner(String name) { this.name = name; } Inner() { } // 静态类里可以有普通方法 public void sayHello() { // 展示静态内部类访问外部类的方式。 // System.out.println(n1); 不能直接访问外部类非静态成员变量 System.out.println(new Outer().n1); // 但是可以通过创建外部类实例来访问外部类非静态变量 System.out.println(Outer.n2); // 可以直接访问外部类静态变量 System.out.println(n2); // 直接访问遵循就近原则 System.out.println("Hello, I'm " + this.name); // 也可以访问本类非静态变量 System.out.println("Total count: " + count); // 也可以访问本类静态变量 } } // 接下来展示外部类如何访问静态内部类 public void accessInner() { Inner inner = new Inner("HSP"); // 创建静态内部类对象 System.out.println(inner.name); // 访问静态内部类成员变量 System.out.println(Inner.count); // 访问静态内部类静态成员变量 } public Inner getInnerInstance(String name) { return new Inner(name); // 创建静态内部类对象并返回给调用方 } public static Inner getInnerInstance_(String name) { return new Inner(name); // 创建静态内部类对象并返回给调用方 } } 综合练习 练习1 当前代码会不会报错?为什么? public class Test { class Inner { public int a = 5; } public static void main(String[] args) { Inner r = new Inner(); } } 答案: 会报错,因为成员内部类在创建时依赖外部类的实例而存在,需要一个外部类作为容器,传统初始化方法为 “外部类实例.new 成员内部类名” main方法是静态的,静态方法中没有this关键字,因而报错,下面这样做就可以 public class Outer { public class Inner { } // 实例方法(非静态方法) public void show() { Inner inner = new Inner(); // ✅ 可以! // 等价于:this.new Inner(); // 因为实例方法中,this 指向当前 Outer 对象 } } 练习2 下面这段代码会输出什么? public class Test { public Test() { Inner s1 = new Inner(); s1.a = 10; Inner s2 = new Inner(); System.out.println(s2.a); } class Inner { public int a = 5; } public static void main(String[] args) { Test t = new Test(); Inner r = t.new Inner(); System.out.println(r.a); } } 答案: 5 5 分析: Test构造器里初始化的 S1 和 S2 分别是两个不同的成员内部类实例,而 main 方法里初始化的 r 也是一个不同的成员内部类实例。三个方法中的 a 是独立的 1 个帖子 - 1 位参与者 阅读完整话题
要临时用下基础闹钟了
我先说说我的观影方案 基础信息 播放器:Apple TV 4K + infuse 电视:小米4K 85英寸 影视资源:PT(社区里也经常有佬友发邀请) 存储:NAS(白群晖4盘 * 16T) 媒体库自动化管理:MP 部署方案: NAS容器化部署: qb(下载) mp(媒体管理+企业微信通知交互) 实现效果: 远程微信交互进行订阅/下载 自动下载并整理+通知 回家观影 6 个帖子 - 5 位参与者 阅读完整话题