前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java"小心机"(1)【资源彩蛋!】

java"小心机"(1)【资源彩蛋!】

作者头像
KEN DO EVERTHING
发布2019-01-17 14:56:44
4100
发布2019-01-17 14:56:44
举报
文章被收录于专栏:KEN DO EVERTHINGKEN DO EVERTHING

阅读本文大概需要9分钟

java"小心机"系列文章在此开篇。在这,将会给你带来曾经错过、忽略或感到模糊的知识,也许它很基础,微不足道,但它能修复知识漏洞,夯实地基,建立更全面的知识体系。

1.一个类中,以什么标识某个方法

方法名和参数列表(它们合起来被称为“方法签名”)唯一地标识出某个方法。(引用自[Thinking in java])

关联知识点:返回值是否能区分重载方法?

我们来看下以下例子中两个方法

代码语言:javascript
复制
void f() {};
int f() { return 1; };

调用方法注重返回值时,比如在int i = f()中,确实可以区分重载方法。但有时,你并不关心返回值,只想要方法调用的其他效果,这时你可能会调用方法而忽略返回值。就像这样:f(); 此时,我们是无法理解这种代码的?更何况是机器? 因此,根据返回值区分重载方法时行不通的。(java中也禁止例子中的代码,编译是不通过的)

2.java包的静态导入

使用import static可导入某个包中的static成员,后缀*导入全部static成员

代码语言:javascript
复制
import static java.lang.System.out;
import static java.lang.Integer.*;

public class Test{
    public  static  void  main(String[] args){
        out.println("hello java");
        out.println(MAX_VALUE);
        out.println(MIN_VALUE);
    }
}

结果:

代码语言:javascript
复制
hello java
2147483647
-2147483648

从以上代码可以看到,静态导入System.out,直接使用

out.println()==System.out.println(),

Integer类也是如此,

MAX_VALUE==Integer.MAX_VALUE,

MIN_VALUE==Integer.MIN_VALUE

优点:简化代码 缺点:降低了代码可读性 建议:大量使用了某个类的静态成员时可考虑使用(代码简洁与可读性的取舍,结合实际情况吧)

3.自增自减的前后缀式(初学者较难理解的点)

前缀式:先执行运算,再生成结果 后缀式:先生成结果,再执行运算

代码语言:javascript
复制
import static java.lang.System.*;

public class AutoInc {
    public static void main(String [] args){
        int i = 1;
        out.println("i  " + i);
        out.println("++i : " + ++i);
        out.println("i++ : " + i++);
        out.println("i : " + i);
        out.println("--i : " + --i);
        out.println("i-- : " + i--);
        out.println("i : " + i);
    }
}

结果:

代码语言:javascript
复制
i : 1
++i : 2
i++ : 2
i : 3
--i : 2
i-- : 2
i : 1

分析: ++i先运算i+1再生成结果i=2 i++先生成结果i(略掉自增符号即为结果),再运算i-1

我们再看下一题(别看结果,试着做一下):

代码语言:javascript
复制
z=3、x=1、y=2 
问z -= --y - x--
此时z =?, y=?,x=?

结果为:

代码语言:javascript
复制
z=3
y=1
x=0

运算步骤: 1.--y -> y = y -1 = 1 2.x--此处为后缀式,先生成结果z- = y-x(忽略自减符号即为结果),则z = z - (y - x) = 3,再运算x-- ->x = x-1= 0

4.类型转换(扩展转换和窄化转换)

扩展转换:即较类型赋值给较类型时进行的类型转换。较大类型肯定可以容纳较小类型的信息,不会造成信息丢失,无需进行显示转换,编译器会自动将进行转换(隐式转换)。 窄化转换:即较类型赋值给较类型时进行的类型转换。较小类型可能无法容纳较大类型的信息,可能会造成信息丢失,需要进行显示转换

代码语言:javascript
复制
public class Casting {
    public static void main(String[] args){
        int i = 100;
        long lng1 = i;//扩展转换,无需显示转换
        lng1 =(long) i;//"多余的"显示转换,可提醒自己需要留意
        long lng2 = 200;
        i = (int) lng2;//窄化转换,必须显示转换,否则报错
    }
}
5.类型提升

对基本数据类型执行算术运算或按位运算时,表达式中出现的最大的数据类型决定了表达式最终结果的数据类型,较小的数据类型会在运算时自动转换成该结果类型。 例子:

代码语言:javascript
复制
int i = 1;
long lng = 2;
long result = i + lng;//运算前,`int i`自动转换为long类型
6.基本类型包装类的常量池

java面试|精选基础题(2)一文中就有提到Integer的常量池,其实java中基本类型的包装类的大部分都实现了常量池技术。 对包装类进行赋值时,字面量值在[-128,127]间时,将使用常量池中对象,反之则创建新的对象。

  • 已实现常量池的类: Byte,Short,Integer,Long, Character,Boolean
  • 未实现:Float,Double

看一下以下代码:

代码语言:javascript
复制
public class Cache {
    public static void main(String[] args){
        //实现常量池的包装类以Long为例
        //在值小于127,可以使用常量池
        Long i1 = 127L;
        Long i2 = 127L;
        System.out.println(i1 == i2);//输出true

        //值大于127,不会从常量池中取对象
        Long i3 = 128L;
        Long i4 = 128L;
        System.out.println(i3 == i4);//输出false

        //Boolean类也实现了常量池技术
        Boolean bool1 = true;
        Boolean bool2 = true;
        System.out.println(bool1 == bool2);//输出true

        //浮点类型的包装类没有实现常量池技术
        Float f1 = 3.0f;
        Float f2 = 3.0f;
        System.out.println(f1 ==f 2);//输出false

        Double d1 = 1.0;
        Double d2 = 1.0;
        System.out.println(d1 == d2);//输出false
    }
}

若想深究其原理,首先需要了解其中装箱的本质是什么?(可看java面试|精选基础题(2)文中第一题)将基本类型赋值给包装类时,实际上执行了包装类的valueOf方法。 以Long为例,看一下相关源码(其他包装类常量池实现方法类似) valueOf方法源码:

代码语言:javascript
复制
    public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

可以看出,当字面量值在[-128,127]间,返回LongCache中的值 再来看LongCache(Long常量池)源码:

代码语言:javascript
复制
 private static class LongCache {
        private LongCache(){}

        static final Long cache[] = new Long[-(-128) + 127 + 1];

        static {
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Long(i - 128);
        }
    }

LongCache是Long的静态内部类,虚拟机加载Long类就会将[-128,127]的值存储在Long cache[]中。


重磅好消息:小编考虑到同学们对学习资源的迫切需求,近期将整理出学习视频库和电子书库,你想要的资源全在这里,该资源永久有效,不断更新,敬请期待!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java从心 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.一个类中,以什么标识某个方法
    • 关联知识点:返回值是否能区分重载方法?
    • 2.java包的静态导入
    • 3.自增自减的前后缀式(初学者较难理解的点)
    • 4.类型转换(扩展转换和窄化转换)
    • 5.类型提升
    • 6.基本类型包装类的常量池
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档