java基础加强视频学习(—)
1.elcipse关不了了,关闭进程javaw。
2.eclipse运行版本问题:
![](http://dl.iteye.com/upload/attachment/0066/8912/9edd209c-e8ce-3285-8b20-d81bfa20e366.png)
3.调试技巧:
选择变量,右击选择watch。可以查看变量的值。
4.模板设置
![](http://dl.iteye.com/upload/attachment/0066/8914/f7311425-678f-3498-98e1-cd836ecca5c6.png)
5.静态导入:
导入一个类的静态方法。
如:
import static java.lang.Math.*;
6.可变参数:
public static void main(String[] args) {
System.out.println(add(1,2,4));
System.out.println(add(1,2,4,5));
}
public static int add(int x, int... args){//可变参数
int num=0;
for (int i = 0; i < args.length; i++) {
num+=args[i];
}
return num;
}
ctrl+shift+/注释整个段落
7.增强for循环
上面代码:
for (int i : args) {
num+=i;
}
8.装箱和拆箱
public static void main(String[] args) {
Integer integer1 =12;
Integer integer2=12;
System.out.println(integer2==integer1);
}
返回true
public static void main(String[] args) {
Integer integer1 =150;
Integer integer2=150;
System.out.println(integer2==integer1);
}
返回false
因为如果装箱成Integer类型时,如果数值在-128-127之间,会缓存起来。所以第一程序是true。第二个是false。这实际运用的是一个享元模式。
享元模式:有很多小的对象,他们有很多相同的属性,那些相同的属性把它们变成一个对象,称之为外部状态,不同的属性变成方法的参数。称之为外部状态。
9.枚举
在编译程序时,发现你的值是否合法。
用普通的java类实现枚举
public class Static {
public static void main(String[] args) {
Weekday sun=Weekday.sun;
System.out.println(sun.toString());
}
}
class Weekday{
private Weekday(){}
public final static Weekday sun=new Weekday();
public final static Weekday mon=new Weekday();
public Weekday netxDay() {
if (this==sun) {
return mon;
}
else {
return sun;
}
}
public String toString() {
return this==sun?"sun":"mon";
}
}
使用内部类实现上例:把大量的if-esle转换成独立的类。
public class Static {
public static void main(String[] args) {
Weekday sun=Weekday.sun;
System.out.println(sun.toString());
}
}
abstract class Weekday{
private Weekday(){}
public final static Weekday sun=new Weekday(){
@Override
public Weekday nextDay() {
return mon;
}
};
public final static Weekday mon=new Weekday(){
@Override
public Weekday nextDay() {
return sun;
}};
public abstract Weekday nextDay();
/* public Weekday netxDay() {
if (this==sun) {
return mon;
}
else {
return sun;
}
}*/
public String toString() {
return this==sun?"sun":"mon";
}
}
点击变量名,再点击右键Refacter,就可以对所有相同的变量改名。
枚举:
public static void main(String[] args) {
WeekDay weekDay=WeekDay.mon;
System.out.println(weekDay.valueOf("sun").toString());
}
public enum WeekDay{
sun,mon;
}
枚举类的构造方法必须是私有类型。
public static void main(String[] args) {
WeekDay weekDay=WeekDay.mon;
System.out.println(weekDay.valueOf("sun").toString());
}
public enum WeekDay{
sun(1),mon;
private WeekDay(){System.out.println("first");}
private WeekDay(int x){System.out.println("second");};
}
输出结果:
second
first
sun
枚举实现抽象方法:
public enum WeekDay {
sun(1){
@Override
public WeekDay nextDay() {
return mon;
}
},
mon(2){
@Override
public WeekDay nextDay() {
return sun;
}
};
public abstract WeekDay nextDay();
int time;
private WeekDay(int time) {
this.time = time;
};
}
10.如何获得各个字节码对应的实例变量。
public class Test2 {
public static void main(String[] args) {
Person person=new Person();
Class class1 =person.getClass();//获得字节码方式1
try {
Class class2 =Class.forName("Person");//获得字节码获得字节码方式2
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class class3 =Person.class;//获得字节码方式三
}
}
class Person{}
预定义9个对象:
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
11.反射的概念:
反射就是把java类中的各种成分映射成相应的java类。
获取构造函数:
Constructor constructor=String.class.getConstructor(StringBuffer.class);
String str2 =(String)constructor.newInstance(new StringBuffer("zengxiao"));
Class.newInstance()构建不带参数的构造方法。
Field 获取是字节码的属性。
对字节码的比较用==比。
一个反射经典例子:
将任意一个对象中的所有String类型的成员变量所对应的字符串中的"b"改成“a”
public class ReflacterTest3 {
public static void main(String[] args) throws Exception{
Zengxiao zengxiao=new Zengxiao();
changString(zengxiao);
System.out.println(zengxiao);
System.out.println(zengxiao.toString());
}
private static void changString(Object obj)throws Exception {
Field[] fields =obj.getClass().getFields();
for (Field field : fields) {
if (field.getType()==String.class) {
String oldValue=(String) field.get(obj);
String newValue=oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}
};
}
class Zengxiao{
public String str1 ="ball";
public String str2 ="basketball";
public String str3 ="aaacc";
@Override
public String toString() {
return str1+":"+str2+":"+str3;
}
}
Method
Method method =String.class.getMethod("charAt", int.class);
System.out.println(method.invoke(str1, 2));
如果:
invoke(null,2);证明是传入一个静态方法。
在类名上按下F2可以查出完整的类名。
hashset和hashcode
public class ReflacterTest4 {
static String str1="abc";
public static void main(String[] args){
Collection<Zeng> collection =new HashSet<Zeng>();
Zeng zeng1 =new Zeng(1, 2);
Zeng zeng2 =new Zeng(1, 2);
Zeng zeng3=new Zeng(3, 2);
collection.add(zeng1);
collection.add(zeng2);
collection.add(zeng3);
System.out.println(collection.size());
}
}
class Zeng{
public Zeng(int x, int y) {
this.x = x;
this.y = y;
}
/*@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Zeng other = (Zeng) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}*/
int x;
int y;
}
用反射技术开发框架的原理:
框架与框架要解决的核心问题
我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中。框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
你做的门调用锁,锁是工具,你做的门被房子调用,房子时框架,房子和锁都是别人提供的。
·框架要解决的核心问题
-我在写框架(房子)时,你这个用户可能还在上小学,还不会写程序呢?我写的框架程序怎么样能调用到你以后写的类(门窗)呢?
-因为在写程序时无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象类,而要用反射方式来做。
config.properties
className=java.util.HashSet
public class ReflacterTest4 {
static String str1="abc";
public static void main(String[] args) throws Exception{
//一定要记住用完整的路径,但完整路径不是硬编码,而是运算出来的。
InputStream ipStream =new FileInputStream("config.properties");
Properties props =new Properties();
props.load(ipStream);
ipStream.close();//关闭物理资源
String className =props.getProperty("className");
Collection<Zeng> collection =(Collection<Zeng>)Class.forName(className).newInstance();
//Collection<Zeng> collection =new HashSet<Zeng>();
Zeng zeng1 =new Zeng(1, 2);
Zeng zeng2 =new Zeng(1, 2);
Zeng zeng3=new Zeng(3, 2);
collection.add(zeng1);
collection.add(zeng2);
collection.add(zeng3);
System.out.println(collection.size());
}
}
class Zeng{
public Zeng(int x, int y) {
this.x = x;
this.y = y;
}
int x;
int y;
}
类加载器:
getRealPath()获得项目的路径
InputStream ipStream=ReflacterTest4.class.getResourceAsStream("config.properties");
//会找包下面是否有config.properties文件,你只要把config.properties放在classpath目录就可以了,这样保证解决了相对文件的问题。
("config.properties")不能写成("/config.properties")这个是规定。
这种方法只能读不能写。
内省----JavaBean
Alt+Shift+S菜单
抽取方法:
右击---Recftor--Extract Method
![](http://dl.iteye.com/upload/attachment/0066/8916/0093ed4e-5aaa-3f2f-bb56-0b32bbd02c60.png)
使用BeanUtils工具包操作JavaBean
public class IntroSpectorTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ReflectPoint pt1 = new ReflectPoint(3,5);
String propertyName = "x";
//"x"-->"X"-->"getX"-->MethodGetX-->
Object retVal = getProperty(pt1, propertyName);
System.out.println(retVal);
Object value = 7;
setProperties(pt1, propertyName, value);
System.out.println(BeanUtils.getProperty(pt1, "x").getClass().getName());
BeanUtils.setProperty(pt1, "x", "9");
System.out.println(pt1.getX());
/*
//java7��������
Map map = {name:"zxx",age:18};
BeanUtils.setProperty(map, "name", "lhm");
*/
BeanUtils.setProperty(pt1, "birthday.time", "111");
System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
PropertyUtils.setProperty(pt1, "x", 9);
System.out.println(PropertyUtils.getProperty(pt1, "x").getClass().getName());
}
private static void setProperties(Object pt1, String propertyName,
Object value) throws IntrospectionException,
IllegalAccessException, InvocationTargetException {
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1,value);
}
private static Object getProperty(Object pt1, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
/*PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
Method methodGetX = pd.getReadMethod();
Object retVal = methodGetX.invoke(pt1);*/
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
if(pd.getName().equals(propertyName))
{
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
break;
}
}
return retVal;
}
}
12.注解
1、注解相当于一种标记,可以通过反射获得,可以给包,类,方法,变量等加注解,jdk中提供的最基本的注解 Annotation
2、Deprecated 用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
3、Override 表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类法,则编译器会生成一条错误消息。
4、SuppressWarnings指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。
注解的定义与反射调用
1、注解类
@interface A{
}
2、应用了"注解类"的类
@A
class b{
}
3、对"应用了注解类的类"进行反射操作的类
class c{
b.class.isAnnotaitonPresent(A.class);
A a = B.class.getAnnotation(A.class);
}
4、根据反射测试的问题,引出@Retention元注解的讲解三种取值
RetentionPolicy.SOURCE java源文件
RetentionPolicy.CLASS class文件
RetentionPolicy.RUNTIME 内存中字节码
默认是在class阶段,运行时,是不显示的,编译时显示
5、思考阶段
@override source 阶段
@SuppressWarnings source 阶段
@Deprecad class阶段
6、RetentionPolicy为枚举类型
为注解增加各种属性
1、数组类型的属性
int[] arrayAttr() default{3,2,4}
@MyAnnotation(arrayAttr={33,33})
2、枚举类型
EnumTest.TrafficLamp lamp();
@MyAnnotation(lamp=EnumTest.TrafficLamp.Green)
3、注解类型的属性
MetaAnnotation annotationArrt() default @MetaAnnotation("xxx")
@MyAnnotation(annotationAttr=@MetaAnnotation("yyy"))
可以认为上面这个@MyAnnotation是MyAnnotation类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotaion类的一个实例对象,调用代码如下
MetaAnnotation ma = myAnnotation.annotationAttr();
System.out,println(ma.value())
4、查看language.specification
package com.itcast.day2;
@ItcastAnnotation(color="red", value = "abc", arrayArray = { 1,2 })//使用注解的属性,当数组属性只有一个元素时,可以不写大括号
//@ItcastAnnotation("abc")//使用注解的属性,当只有value属性时,可以直接写值
public class AnnotationTest {
@SuppressWarnings("deprecation")//压缩警告,告诉程序说,我知道已经过时了,不提示
public static void main(String[] args) {
System.runFinalizersOnExit(true);
sayHello();
if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){//判断是否是注解
//获取注解对象
ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
System.out.println(annotation);
System.out.println(annotation.color());//s使用注解的属性,调用方法
System.out.println(annotation.arrayArray().length);//s使用注解的属性,调用方法,数组属性不能转换为list打印出来
}
}
@Deprecated//表明该方法已过时
public static void sayHello(){
System.out.println("hi,传智播客");
}
@Override//表明是覆盖方法,如果写错会提示
public String toString(){
return null;
}
}