java 学习 语言特色。

Wesley13
• 阅读 551

1.总体来说java像一个不开窍的规则制定者。

包名,类型,太实在了。

文件名和类名必须对应,一个文件只能有一个 PUBLIC的类。

定义了包名,必须按这个路径去放置 目标文件。

相比 c#的 虚拟命名空间。

可能java最初就是设计出来让人用记事本来写代码的?而且还怕人找不到类放在哪个目录,哪个文件下。

一个文件只能一个public类,简直无语,所以才会产生静态内部类,这种怪胎的概念。

有非静态类还好解释,让非静态类实现顶级类应该实现的接口,让顶级类看起来更简洁。但是静态内部类 真的是java的特色奇葩。****

2.默认的访问是private+  packet. .奇怪的设定。

突然想到了这个设定的用意。还一直在回想vs中,有解决方案,项目这样的设定,并可以独立开发。非常简单的引用。

突然就想到。默认的访问权限就是 非常适合解决分层的问题。一个包内,全部都是包内访问权限。之后再来一个public 的类。这不就是妥妥的分层设计不。不过加大了工作。要新一个pulick类。还是。。。

3.不可以初始化泛型数组  T[] a=new T[3]; 错误的。

4.java 的异常处理。和c#一样,可以在catch中自己处理,也可以只做抛出动作,让使用者自己处理的机制。

   而且java 更明确了。在方法后面跟了一个throws 关键字,明确的告诉使用者,我不会处理,你自行处理某些异常。

   这样让每个异常从最底层到最上层,确保一定会有一个处理 者。

5.匿名类所使用外部变量必须final

我自己的感觉是因为有匿名,所以无法控制语句的执行顺序,因为匿名函数可能随时被一个新线程处理。把变量设置为null或其他对象。

所以非常影响主函数的执行,主函数的逻辑可能被完全打乱。出现问题。都无法排错。因为非线性执行。

所以到匿名内部不能使用变量的正常引用,所以给一个不正常的引用。就是不让你指向其他对象,无法修改指针本身。

这里有比较正确的解释:https://zhuanlan.zhihu.com/p/29245059

基本原因就是,当匿名类使用栈上的数据(方法内部的数据)时候,如果方法内部或匿名内部修改了指针,由于编译的问题,无法让2者保持一致。所以干脆2个地方都不让修改指针。恩,解释目前是完美自洽的。

如果需要改指针,那么用普通类代替匿名类,反正自己也不是很喜欢匿名类。不好看,而且减低了复用的意识。

6.为什么需要内部类

  2种,非静态类和静态类,我觉得分别叫扩展类和帮助类,更容易让人知道这2中类的作用。

Compelling reasons for using nested classes include the following:

  • It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

  • It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

  • It can lead to more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used.

Static Nested Classes:除了命名空间需要使用顶级类 topclass.myclass xxx=new topclass.myclass() .其他和顶级类一样。虽然有static 也需要new.

一个很明显的时候场合就是建立一个只有外部类会用到的帮助类。

Non-Static Nested Classes(inner class) .就可以看成顶级类的一个 内部变量,如内部的一个string之类。

一个很明显的使用场合就是多接口的时候,用一个内部类实现接口,把接口实现从外部类放到内部类,这样可以让外部类代码看起来更整洁。如此,内部类其实就是外部类的一部分,就像一个成员变量。

7.如何选择,

就看是否需要顶级类的成员变量。需要那么非静态。 不需要那么静态。 

static看成一个顶级类就可以了。只不过访问路径被外部类套住了。这个关键字又是一个误导关键字。static在这里和全局,不需要new没有关系。statci换成 Top, outer ,任何表示外部独立的单词都比static 好。****

而非静态类,他就看成一个类的成员变量就好了,只不过这个成员变量,可以有自己变量和方法而已。唯一注意的就是它本身不能有static变量,感觉真无聊。干脆让它有static变量不就好了。搞的要多记一个特殊点。而且这个特殊点和逻辑无关。因为就算他有static变量。感觉也不影响任何操作。没有反而让人更不适应。他有static会怎样。不就和外部类的static变量一样的使用?而且有的话。还可以限制static变量的使用范围。缩小到内部类。

很多可行可不行的东西。不需要解释那么多无聊的意义。

8 。值和引用。

不算java的特色了。大部分高级语言都有。这里小结下。

没有类之前,基本数据类型占用的内存是固定的并且是小的,如4字节,8字节等。所以基本类型一般是直接放入到栈中。如此,当作为参数传递时,也是可以直接把数据本身copy一份传递过去。导致函数内外是2份数据,互不影响。

而有了类,类占用的内存不可能是固定大小的(但是每个类占用的内存是确定的,不会变化,只是大小不同),有的会很大。所以最好放入到堆中,而用一个4字节(32位系统)的地址来指代它。所以作为参数,是把指针传递,所以函数内外是同一份数据,2个存放同一地址的4字节空间。

这里比较好理解。

但是有个类,string,却不符合典型类的特性。string作为参数,函数内外修改后,并不会是同一份数据。

个人的猜测还是和编译有关,因为string的特性已经不符合人的习惯而且还和其他类也不同,所以肯定是没有办法才这样设计。

猜测是:其他类,如果只包含基本类型。那么修改后,是不会改变内存大小的。

而string类,修改值是会改变内存大小的。这个就不好办了。不能在原来堆中直接修改数据,因为大小是不一样。直接扩大也不能保证后面有足够大的空间。只能让系统按算法给个适合大小的另外的堆空间。

所以string类,每次修改值,其实都是new了一次。既然new了一次。那么函数内外当然是2分数据了。别说函数内外。就是上下2行,修改数据也是不同堆地址,不同引用。 所以是因为现实的无奈导致语意的不统一。

总结

基本类型,固定大小,且小。所以可以到处copy本身。如 int 3. 到处传递和保存 00000011 ,互不干涉。

典型类:放入堆中,用指针代替,到处传递指针,修改原堆数据来进行修改数据。(如里面有个int32变量,4改为3000,在原来4字节的地方修改,可以原地改)

string:放入堆中,用指针代替,到处传递地址,但是无法在原堆数据进行修改(因为对于string修改基本会导致所占空间变化),每次修改必须换一个新的地址。

所以如果想函数外得到修改后的string或者基本数据,那么把string和基本类型放入到类就好了。所以如果函数内 abc=new xxx();也当然不会修改函数外了。因为没有修改指向堆的数据,而是换了一个地址。

本质清楚了,任何情况只要推一下就好。

所以理论上java缺少一个关键字,控制典型类被传递后,不会被修改数据本身。好像没有c++的const关键字。final 只能给基本类型控制数据不能修改

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
3年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这