一.泛型与类型擦除
最初的泛型是在C#语言中,自JDK1.5开始,java引入了泛型,但他们还是不同的;
在C#中的泛型,List<int>和List<String>就是两种不同的类型,他们是运行期生成的,这种实现成为类型膨胀,是真实泛型;但在java中,List<int>和List<String>同属于List类型,编译后会类型擦除,参数使用会被类型强转;
源代码:
/**
* 在源代码中存在泛型
*/
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("hello","你好");
String hello = map.get("hello");
System.out.println(hello);
}
编译后代码:
public static void main(String[] args) {
HashMap map = new HashMap(); //类型擦除
map.put("hello", "你好");
String hello = (String)map.get("hello");//强制转换
System.out.println(hello);
}
为何说泛型其实是一种类型呢?
这两个方法重载失败,类型消除后拥有相同的签名;
二. 自动装箱与拆箱,变长参数
1.自动装箱与拆箱
java的思想是面向对象编程,这也是其一直沾沾自喜的地方,但是被人抨击的一点就是java中的基本类型,这也在实际应用应用中产生了诸多不便,因此包装类产生了;并且基本类型和包装类型之间可自动拆装箱,这是一个语法糖;
扫描二维码关注公众号,回复:
127473 查看本文章
源代码:
public static void main(String[] args) {
Integer a = 1;
int b = 2;
int c = a + b;
System.out.println(c);
}
编译后:
public static void main(String[] args) {
Integer a = Integer.valueOf(1); // 自动装箱
byte b = 2;
int c = a.intValue() + b;//自动拆箱
System.out.println(c);
}
2.变长参数
源代码:
public class Varargs {
public static void print(String... args) {
for(String str : args){
System.out.println(str);
}
}
public static void main(String[] args) {
print("hello", "world");
}
}
编译后:
public class Varargs {
public Varargs() {
}
public static void print(String... args) {
String[] var1 = args;
int var2 = args.length;
//增强for循环的数组实现方式
for(int var3 = 0; var3 < var2; ++var3) {
String str = var1[var3];
System.out.println(str);
}
}
public static void main(String[] args) {
//变长参数转换为数组
print(new String[]{"hello", "world"});
}
}
三.增强for循环
相比于普通的for循环,更加简洁和易懂;
源代码:
public static void main(String[] args) {
String[] params = new String[]{"hello","world"};
//增强for循环对象为数组
for(String str : params){
System.out.println(str);
}
List<String> lists = Arrays.asList("hello","world");
//增强for循环对象实现Iterable接口
for(String str : lists){
System.out.println(str);
}
}
编译后:
public static void main(String[] args) {
String[] params = new String[]{"hello", "world"};
String[] lists = params;
int var3 = params.length;
//数组形式的增强for退化为普通for
for(int str = 0; str < var3; ++str) {
String str1 = lists[str];
System.out.println(str1);
}
List var6 = Arrays.asList(new String[]{"hello", "world"});
Iterator var7 = var6.iterator();
//实现Iterable接口的增强for使用iterator接口进行遍历
while(var7.hasNext()) {
String var8 = (String)var7.next();
System.out.println(var8);
}
}
四.内部类与枚举
1.内部类
内部类之所以是语法糖,是因为其只是一个编译时的概念,一旦编译完成,编译器就会为内部类生成一个单独的class文件,名为outer$innter.class。
源代码:
public class Outer {
class Inner{
}
}
编译后:
class Outer$Inner {
Outer$Inner(Outer var1) {
this.this$0 = var1;
}
}
2.枚举
枚举类的定义使用enum。在Java的字节码结构中,其实并没有枚举类型,枚举类型只是一个语法糖,在编译完成后被编译成一个普通的类。这个类继承java.lang.Enum,并被final关键字修饰。
源代码:
public enum Fruit {
APPLE,ORINGE
}
编译后:
public final class Fruit extends Enum
{
public static Fruit[] values()
{
return (Fruit[])$VALUES.clone();
}
public static Fruit valueOf(String s)
{
return (Fruit)Enum.valueOf(Fruit, s);
}
private Fruit(String s, int i)
{
super(s, i);
}
//枚举类型常量
public static final Fruit APPLE;
public static final Fruit ORANGE;
private static final Fruit $VALUES[];//使用数组进行维护
static
{
APPLE = new Fruit("APPLE", 0);
ORANGE = new Fruit("ORANGE", 1);
$VALUES = (new Fruit[] {
APPLE, ORANGE
});
}
}