黑马程序员 个人对JDK1.5新特性的一点总结

-----------android培训、java培训、java学习型技术博客、期待与您交流! ------------.......

1,在JDK1.5以后才有的,静态导入的方法.
import static 

2,可变参数,这也是在 JDK1.5出现的新特性.可变参数的特点;
a)只能出现在参数列表的最后
b)... 位于变量类型和变量名之间,前后有无空格都可以.
c)调用可变参数的方法时,编译器为该可变参数隐含创建一个数组
在方法体中以数组的形式访问可变参数.
如;
main(int...arr)//这就是一个可变参数的形式.
这里面也是有角标的,
for(int i =0 ; i< arr.length; i++){

}
用这样的方式来遍历.里面的元素.


----------------------------------------------------------------------
3增强for 循环.
语法结构是;
for(类型    变量名  : 集合变量名){....}
要注意的事项
迭代变量必须在()定义!
集合变量可以是数组或实现了 Iterable 接口的集合类
Iterable 可迭代的

----------------------------------------------------------------------

4,基本数据类型的自动拆箱和装箱.
自动装箱;
Integer unm1=12;

自动拆箱
System.out.println(unm1+12);

基本数据类型的对象缓存;
如果一个数字实在一个字节(byte),的范围之内的话,
入果把这一个相同的数字,封装成Integer 不同
两个对象的话那么他们在内存中地址值是一样的.
Integer unm1=12;
Integer unm2=12;
System.out.println(unm1==unm2);

享元设计模式,flyweight,有很多很小的对象他们有很多属性
都是相同的,那些不同属性,把他们变成方法的参数称之为外部状态
,相同属性称之为这个对象的内部状态,那么我们
可以 把它封装成一个对象,这样做就是享元设计模式.

----------------------------------------------------------------------
枚举;
为什么要有枚举呢?
问题;要定义星期几或性别的变量,该怎么定义呢?假设1-7分别表示
星期一到星期日 但有人可能会写成 int weekday =0;
枚举就是要让摸个类型的变量的取值只能为若干个固定值中的一个,
否则,编译器就会报错,枚举可以让编译器在编译时就可以控制源
程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标

用普通类如何实现枚举功能,定义一个Weekday的类来模拟枚举功能
代码如下;
class Demo{

	WeekDay weekDay = WeekDay.p;
	
	System.out.println(p2.getWeekDay());
}
class WeekDay{
private WeekDay(){}
public static final WeekDay p=new WeekDay();
public static final WeekDay MON= new WeekDay();
	public WeekDay getWeekDay(){
		if(this == p){
		return p;
		}
		else{
			return MON;
		}
	}
	public String toString(){
	
	return this==p?"p":MON;
	}

}
那么在枚举当中封装的都是对象.

定义的元素列表都是静态的都是类名可以直接调用的
,在调用类的时候,元素是要被初始化
的,成员变量先被初始化,调用的都是,空参数的构造方法.
如;
public enum WeekDay{
在枚举类中先定义的是元素,然后才是方法.
	p(1),MON(),TUE,WED,THI,FRI,SAT;
   创建这个元素的实例对象的时候,用的是哪个构造方法.
	private WeekDay(){
	sop("先输出");
	}
	private WeekDay(int day){
	
	}
}
----------------------------------------------------------------------
reflection 反射不是JDK1.5的新特性.在1.2中就有了
反射只有在做框架的时候才会使用到的.
在Java中用于描述Java类的类的名字就是 Class .
java 中的反射的基石--->class类
Java程序中各个Java类属于同一类食物,描述这类事物的Java类名就是
Class
这个Class 是类名而不是关键字.

每个Class 对应的都是字节码文件.
Person p=  new Person();
Person p1 = new Person();

Data

Math

Class cls1= 字节码1;
Class cls2 = 字节码2;
什么叫做字节码呢?
当我们在原程序中用到了 p 的时候
首先要从硬盘上将这个类的二进制.代码这个类编译成
class 放在硬盘上以后,就是二进制代码将二进制代码
加载到内存里面来.用这些字节码创建出一个个对象出来.
当我的程序中用到了好多类的时候,有多少个类应该就会有
多少份字节码文件.反射就是用来得到字节码文件的.字节码文件
中包含了,类中各个属性,就是可以用字节码文件的实例对象来
获得不同的成员,

每一份字节码就是一个 Class 的实例对象

获取到字节码文件的方式有三种.

第一种方式就是;类名.class 
第二种方式就是;类名的引用.getClass();
第三种方式就是;Class.forName("java.包名.类名");
第三种方式较为常用.但是的到的都是相同一份字节码文件.
他们在内存中是一样的.

Class.forName("java.lang.String");
Class.forName 的作用就是,得到该类的字节码
不过他有两种方式来得到,第一种是,该字节码已经
在虚拟机中存在,只要找到这份字节码文件加载就好了
第二种方式;如果这份字节码内存中还没有存在的话
那么先用内加载器加载进虚拟机,在用该方法返回,即可.

在反射中有九中,预定义格式,八种是基本数据类型.
原始类型
第九种是,void 
数组类型的Class实例对象
用的是isArray();方法
总之,只要是在源程序中出现的类型,都是有各自的Class 实例对象
例如 int[] void....等等
----------------------------------------------------------------------------
什么叫做反射呢?获取构造方法 constructor来完成的.
反射就是把java类中的各种成分映射成相应的java类.例如;
一个java类中 用一个Class 类的对象来表示,一个类中的组成部分
成员变量,方法,构造方法,包等等信息也是用一个个java来表示的,就像
汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类,表示
java类的Class 类显然要提供一系列的方法,来获得其中的变量
方法,构造方法,修饰符,包括信息
这些信息就是用相应类的实例对象来表示 他们是
Field Method Contructor Package等等;
反射的缺点就是会导致,电脑性能变慢,比较耗用性能.

我们拿到这些对象以后就相当于拿到了里面的成员(成员方法和成员变量),
如我现在有一个类里面有两个方法
class Demo{
public void show(){}
public void run(){}
}
Math m= Demo.show();
m 现在就相当于一个字节码文件.

一个类中的每个成员都可以用相应的反射API类的一个实例对象
来表示,通过调用Class 类的方法可以得到这些实例对象后,得
到这些实例对象后有什么用呢?怎么用呢?这正是学习和应用反射
的要点.

如果是想得到,指定的构造方法,就要明确该构造方法的,参数类型是什么样的
class Demo{
String name;
Demo(String name){
	}
}
如果我想的到该构造方法,那么我就要明确构造方法的参数类型是什么类型的,上面的代码是String
Constructor c=Demo.class.getConstructor(Strign.class);这样就可以得到了指定的构造方法

c.newInstance("zhangsan");这是在利用构造方法在创建对象.
这样做的话说明对象就有了和new Demo();是一样的,只要向里面传入参数即可.
new Demo("zhangsan");

Demo d= new Demo("zhangsan");和 Demo d= (Demo)c.newInstance("zhangsan");是一样的,
两个  d 的用法就是一样的的了.
 Demo d= (Demo)c.newInstance("zhangsan");反射(reflection)这里为什么要做强转的动作呢?
 因为不知道是什么类型的构造函数,所以要强转一下.

=====================================================================================
reflection 反射中的 Field用于成员变量之间的反射.

Field 代表的是字节码中的变量不代表哪个对象上的
这是在访问公有权限的时候没有问题.
class Demo{
private int x;
public int y;
	Demo(int x,int y){
		this.x=x;
		this.y=y;
	}
}
class Demo1{
	public static void main(String[] args){
		Demo d= new Demo(3,4);
	Field field=d.getClass().getField("y");
	System.out.println(field.get(d););这里就表示,该变量是d这个对象中的.
	}
}
但是呢我想访问里面私有的 变量怎么办呢?
就是在获取的时候有点变化,获取私有的成员变量用的是, getgetDeclaredField();
field.setAccessible(true);下面加上这样一句话就是可以的了.

method 类 代表的是字节码中的方法.
得到某一个方法.
例子;
Method charAt= Class.forName("java.lang.String").getMethod("charAt",int.class);
调用的方法
通常的方式;System.out.println(str.charAt(1));
反射的方式;System.out.println(charAt.inVoke(str.1));
	如果传递给Method 对象的inVoke()方法的一个参数为null 这又意味着什么意思呢?
	说明该Method 对象应该是一个静态的方法.

--------------------------------------------------------------------------------------
数组 和 Object 之间的关系及其反射类型.
数组的反射;
1,具有相同维数(就是一维数组还是二维数组)和元素的类型相同,即具有
相同的Class 实例对象.

2,代表数组的Class 实例对象的getSuperClass()方法返回的
父类为Object 对应的Class 

3,基本类型的一维数组可以被当作Object 类型使用,不能当作
Object[] 类型使用,

4,数组中的反射.
public static void show(Object obj){
		Class cls= obj.getClass();
		if(cls.isArray()){
			int len =Array.getLength(obj);
			for(int i=0; i<len ; i++){
				System.out.println(Array.get(obj, i));
			}
			
		}else{
			System.out.println(obj);
		}
		
	}
你给我的是一个数组那么我把它,拆出来一个一个的打印.
给我的就是一个对象的话那么,我就直接打印.

配置文件 一般都用类加载器加载,
xxxx.properties  配置文件的写法,一般都是键值对的形式存在的.


IntroSpector 内省--->javaBean---->特殊的Java类

int getAge()
void setAge(int age)
符合这一种规则的Java类 我们称之为javaBean
我们可以把他当做普通的类来进行操作.
一般的类不一定可以当做javaBean来处理我要看你类里面有
没有 get set 方法.

-----------------------------------------------------------------
注解;总结,注解相当于一种标记,在程序中加上了注解就等于为程序搭上了
某种标记,以后javac 编译器,开发工具和其他程序可以用反射来了解你
的类记各种元素上有无何种标记,看你有什么标记,就去干相应的事,标记可以
加在包,类 ,字段, 方法,方法的参数 以及局部变量上,
在javaLang包中可以看到JDK中提供的最基本人的 Annotation 标记

注解的应用;
标记是一个特殊的类,那么这个类别人在使用的时候,那个类就应该先定义好
那么这个类怎么定义的呢
@interface A{

}就像定义接口一样的,就是在接口的前面加上了@ 符号来表示.

有三个 关系
1,注解类  <------应用"注解类"<-------对应用了注解类的类进行反射操作的类
@interface A{		@A					Class C{
					Class B{			B.class.isAnnotationPresent(A.class);
					}					A a = B.class.getAnnotion(A.class);
}										}
@retention 源注解的讲解,其中取值分为三个阶段;
RetentionPolicy.SOURCE  RetentionPolicy.CLASS 
RetentionPolicy.RUNTIME 分别对应的是 java源文件--->class文件--->内存中的字节码.

什么是注解的属性呢?
属性就像是一个方法.接口中的方法,我们在调用到属性的时候,就要对其初始化
@interface Demo{
	String color() default "blue";这是在设置属性.属性的默认值是用,default 来设置的.
}
在别的地方调用的时候,
@Demo(color="red")这是在对属性赋值.

当只有value 属性的时候.前面的 value= 是可以不写的.
挡在别的属性有默认值得时候,也是可以不写的.

我们在定义数组的时候,属性的时候档里面只有一个值得时候,大括号是可以不写的.

他们的返回值类型有哪些呢?
八个原始类型,String Class Enum 也可以是前面这些类型的数组,如果不是这几个类型的话编译器就会报错.


一个注解相当于一个胸牌,如果你胸前贴了胸牌,就是传智播客的学生,否则,就
不是.如果还想区分出是传智播客哪个班的学生,这时候可以为胸牌在添加一个属性来进行区分
加了属性的标记效果为 @MyAnnotation(color="red")
定义基本类型的属性和应用属性;
在注解类中 增加String color();
@MyAnnotation(color="red")

-------------------------------------------------------------------------------------------
泛型的基本应用;
泛型的出现免去了强制类型的转换,增强的安全性.
泛型是给编译器看的,现在就是要,穿过编译器,利用反射,向集合中添加元素.
在运行的时候就会把泛型去掉.
List<String> list1= new ArrayList<String>();
ArrayList<Integer> list2= new ArrayList<Integer>();
System.out.println(list2.getClass()==list1.getClass());true

说明他们是同一份字节码文件.

--------
泛型中的术语.
(1)ArrayList<E> 类定义和ArrayList<Integer>类引用中涉及如下术语;
	整个称为 ArrayList<E> 泛型类型.
	ArrayList<E> 中的E 称为类型变量或者是 类型参数
	整个ArrayList<Integer> 称为参数化的类型.
	ArrayList<Integer>中的Integer 称为类型参数的实例或实际类型参数.
	ArrayList 称为原始类型.
(2)参数化类型与原始类型的兼容性.
	参数化类型可以引用一个原始类型的对象,变异报告警告,例如
	collection<String> c= new Vector();可不可以,不就是编译器的一句话的事吗?
	原始类型可以引用一个参数化类型的对象,编译器警告 ,例如
	Collection c= new Vector<String>(); 原来的方法接受一个集合参数,新的类型也要能传进去
(3)泛型的上下界
	Vector<? extends Number> x= new Vector<Integer>();
	只要是Number的子类就可以上界
	
	Vector<? super Integer> x= new Vector<Number>();
	只要是Integer的父类就是可以的.限定了下界 
----------------

在方法上定义泛型的时候要在返回值前面加上,<T> 
public static <T> T show(Object obj){
	return (T)obj;
}
把传进来的 obj 转换成想要的类型

----------
在类上定义泛型的应用.
class Demo<String>{

}

-----------------------------------
类加载器;
我们在java程序中用到一个类,出现了这个类的名字,类加载器首先将这个
类的字节码文件加载进内存,(现将.class文件从硬盘上加载进内存,在对这个class文件进行操作)
这些工作时谁在干的呢?这些事都是类加载器在干,

在java 虚拟机中有多个类加载器.系统默认的主要提供了三个类加载器
每个类加载器会负责特定位置上的类;这三个分别是
BootStrap  ExtClassLoader  APPClassLoader

类加载器本身也是一个java类,在java虚拟机中的第一个类加载器,又是
怎么加载进去的呢?
这个类加载器正是 BootStrap 类加载器.这个类很特殊,他不是java类
所以他不需要被别人加载,它是嵌套在java 虚拟机内核中的,就是java虚拟机
已启动的时候他就在里面了.

BootStrap
这个加载的是 JRE/lib/rt.jar
	|ExtClassLoader
	这个加载的是 JRE/lib/ext/*.jar 文件
 		| APPClassLoader
 		这个加载的是classpath路径下面的所有jar或者目录.
   		
-----------------
类加载器的委托机制;是先从最大的开始找,找不到的话在向下面找

当java虚拟机要加载一个类时,到底派出哪个类加载器去加载呢?
1)首先当前线程的类加载器去加载线程中的第一个类.
2)如果类A中引用了类B,java虚拟机将使用加载类A的类加载器来加载类B
3)还可以直接调用ClassLoader.LoadClass()方法来指定某个类加载器去加载某个类.

每一个类加载器加载类时,又先委托给其上级类加载器.
1)当所有祖宗类加载器没有加载到类,回到发起者的类加载器,还加载不到则就会
抛出异常,就不会再往下在走了.
2)对着类加载器的层次结构图和委托加载原理,解释先前将,
ClassLoaderTest 输出成 jre/lid/ext目录下的jar包中后,
运行结果为 ExtClassLoader的原因.

-----------android培训、java培训、java学习型技术博客、期待与您交流! ------------......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值