初探JAVA小知识点(1)

  今天整理几个java的小知识点,包括static的作用,final的作用,for each循环的原理以及transient的作用。

首先是static

1. static的在java中用的最多的就是静态变量和静态方法,例如

public class StaticExample {
	public static int NUM = 0;

	public static int getNum() {
		return NUM;
	}

	public static void main(String[] args) {
		NUM = 1;
		System.out.println(getNum());
	}
}


这个相信大家都知道,变量NUM和方法getNum()就直接依赖于StaticExample这个类,而不用new一个StaticExample的实例出来。

2. 再一个用的比较多的就是静态代码块

public class StaticExample {
	public static int NUM = 0;

	public static int getNum() {
		return NUM;
	}

	static {
		System.out.println("hello static");
	}

	public static void main(String[] args) {
		NUM = 1;
		System.out.println(getNum());
	}
}


在static块内部的代码会在类加载的时候运行,适合做一些初始化的工作

3.static 另外一个用的很少的功能是,静态内部类,反正我到现在没有主动用过,和普通内部类的区别就是访问一个普通内部类类需要先new一个对象出来,例如classA有一个内部类classB,classA a = new classA(),然后classB b = new a.classB();才能访问,而如果是静态内部类,只需要classB b = new ClassA.classB(),就可以访问了。

同时非静态类不可以有静态成员,而静态类可以有静态成员,非静态类可以访问外部类的非静态成员,而静态类就不可以,这个目前在工作中没有怎么用到过

4. static 类另一个使用的非常非常少,我也是无意间看到的一个功能就是静态导包。

import static java.lang.System.out;

public class StaticExample {
	public static int NUM = 0;

	public static int getNum() {
		return NUM;
	}

	static {
		System.out.println("hello static");
	}
	int tt = 0;

	public static void main(String[] args) {
		NUM = 1;
		System.out.println(getNum());
		out.println("hello import static");
	}
}


就是上面的使用方法,没有get到这种用法的精髓,对于常年使用ide的人来说,简直是多此一举。

然后是final

final关键字的主要作用就是表明是不可修改的。final 修饰类时,表明这个类时不能被继承的,final修饰方法时表示这个类是不能被子类重写的,final修饰变量时,表明该变量时不能被重新赋值的,注意对于基本类型,就是值不能变,而对于一个对象的实例而言,仅仅是对象的引用不能变,而对象里面的值是可以变化的。目前在我的工作中,基本就是用final来定义一些常量,一些资料里介绍,使用final除了不变性以外,很重要的就是JVM会对final做优化,可以提升效率,这个没有测试过。

比较有意思的是for each

平常for each用的挺多的,也知道for each内部用的是iterator,但是没有研究过细节,后来无意中写了一行让我不是很能理解的代码,稍微研究了下。

代码类似下面

import java.util.ArrayList;
import java.util.List;


public class FinalExample {

    
    
    public static void main(String[] args) {
        List<String> stringList = new ArrayList<String>();
        stringList.add("hello");
        stringList.add("world");
        stringList.add("java");
        stringList.add("is");
        stringList.add("great");
        for(String tempString : stringList){
            if(tempString.equals("is")){
                stringList.remove(tempString);
            }
        }
    }

}

当时我的第一反应肯定是运行会报java.util.ConcurrentModificationException,但是实际运行后竟然没有报错,这不科学啊,for each循环的时候是不能进行remove操作的啊。

当时纠结了好一会儿,后来网上百度一下,加看下源码终于弄懂了。


        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }

for each主要就是通过collection内部的hasNext()和next()来进行循环取值的,在remove时,报错的其实是
 if (i >= elementData.length)
                throw new ConcurrentModificationException();

多remove几个以后就会发现,只有remove倒数第二个的时候不会报错,其他时候就会报错。

为什么倒数第二个被remove不会报错呢?因为倒数第二个,remove以后size变为原先的maxSize-1,这时候hasNext()函数中,cursor已经和size相等了,然后就跳出循环,不走next()函数了,实际上最后一个元素并没有被遍历到。


最后一个是transient

这个主要是用于在序列化的时候,声明某个属性不能被序列化,比如一个叫User的class,里面有一个属性叫password,密码这个属性不希望被序列化,那么就在前面加一个transient就好了。


今天就先写到这里了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值