您的位置:首页 > 职场人生

黑马程序员---java学习笔记之java基础加强二

2014-01-17 13:58 369 查看
1、下面是我做的一个实验:

Integer i = 4;
System.out.println(i.toString());
上述代码,可以正常编译运行。

Integer i = 4;
System.out.println((i+3).toString());
上述代码不能够编译成功,说明代数式i+3在自动拆箱后并没有自动装箱。

Integer i = 4;
i = i+3;
System.out.println(i.toString());
上述代码是可以正常编译运行的。

2、总结一下,反射的构造器、字段、以及方法的使用方式:

构造器创建对象使用的是:构造器对象.newInstance(Object... 参数名),字段获取某一对象的字段值使用的是:字段对象.get(Object 对象名),一般方法被对象调用的使用的是方法名.invoke(对象名,Object...参数列表)

3、反射的功能:实现框架的功能。怎么理解呢?开发人员要使用框架去开发项目,框架是在开发人员做项目之前就已经写好的。在框架中,我们写了自己的类,框架可以调用这些类,那为什么框架可以调用我们的类呢?框架是在我们类写出来之前就被写出来的,反射实现了这个细节,反射可以让开发人员调用还未写出来的类。

4、使用反射写框架时,给该工程创建一个配置文件,然后在主函数运行时,先导入该配置文件,读取该配置文件中的一些配置信息。这样主函数中就可以某些类名就可以有更大的范围。

5、获取配置文件有三种方式:1、使用FileInputStream;2、如果配置文件在classpath下,那么可以使用类加载器加载getClassLoader.getResoureAsStream(配置文件绝对路径名);3、直接使用类文件的getResourceAsStream(配置文件相对路径名)

6、所谓javaBean其实就是对具有某些特征的类的一种描述,这种特征是,该类中的某个变量XXX,有其setXXX和getXXX对其操作。javaBean有其独立的处理方式。

7、java为javaBean的处理方式提供了api,这些api称为内省。

8、内省的简单操作

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class IntroSpectorDemo {

public static void main(String[] args) throws Exception {
//使用内省的方式获取javaBean类的属性值

Person p = new Person(23,"zhangsan");
String propertyName = "age";
Object temp = 25;

System.out.println(getProperty(p, propertyName));

setProperty(p, propertyName, temp);
System.out.println(getProperty(p, propertyName));

}

public static void setProperty(Object p, String propertyName, Object temp)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
PropertyDescriptor pd1 = new PropertyDescriptor(propertyName,p.getClass());
Method methodSet = pd1.getWriteMethod();
methodSet.invoke(p,temp);
}

public static Object getProperty(Object p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {
PropertyDescriptor pd = new PropertyDescriptor(propertyName,p.getClass());
Method methodGet = pd.getReadMethod();
Object objGet = methodGet.invoke(p, null);
return objGet;
}

}
class Person
{
private int age;

public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
private String name;

public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

}
9、内省的复杂写法,使用BeanInfo

public static Object getProperty(Object p, String propertyName)
throws IntrospectionException, IllegalAccessException,
InvocationTargetException {

BeanInfo bi =Introspector.getBeanInfo(p.getClass());
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
Object obj = null;

for( PropertyDescriptor pd : pds )
{
if( pd.getName().equals(propertyName) )
{
obj = pd.getReadMethod().invoke(p, null);

break;
}
}
return obj;

10、操作javaBean的第三方包BeanUtils

11、注解

//该注解可以在dos下编译程序时,遇到过时的方法不提示警告
@SuppressWarnings("deprecation")
public static void main(String[] args) {
// TODO Auto-generated method stub

System.runFinalizersOnExit(true);

}

//该注解可以使之后调用该方法的程序获得方法过时的警告!
@Deprecated
public void sayHello()
{
System.out.println("hello java");
}

//
@Override

public boolean equals(Object obj)
{
return this == obj;
}
注解其实就是向编译器传递某种信息,另外,注解在以后的程序使用反射时被得到。

12、自定义注解

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

//该注解是自定义注解的注解,称为“元注解”
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {

}

@CustomAnnotation
public class AnnotationDemo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

if(AnnotationDemo.class.isAnnotationPresent(CustomAnnotation.class))
{
CustomAnnotation ca = (CustomAnnotation)AnnotationDemo.class.getAnnotation(CustomAnnotation.class);
System.out.println(ca);
}

}

}
上述代码的打印结果是:@cn.itcast.day02.CustomAnnotation()

13、注解分为三个阶段:RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME,分别对应的是java源文件,javaclass文件以及java字节码文件。默认的注解阶段是RetentionPolicy.CLASS

14、在自定义注解上加@Target(ElemetType[])可以对该自定义注解的位置进行设定。如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface CustomAnnotation {

}
15、为注解添加属性值

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//该注解是自定义注解的注解,称为“元注解”
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface CustomAnnotation {
//为注解添加属性值
String color() default "xyz";
String value();
int[] arrayA();

}
import java.util.Arrays;

@CustomAnnotation(value="123",arrayA = {7,8,9})
public class AnnotationDemo {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub

if(AnnotationDemo.class.isAnnotationPresent(CustomAnnotation.class))
{
CustomAnnotation ca = (CustomAnnotation)AnnotationDemo.class.getAnnotation(CustomAnnotation.class);
System.out.println(ca.color());
System.out.println(ca.value());
System.out.println(Arrays.toString(ca.arrayA()));
}
}

}
为注解添加属性时,属性的返回值还可以是枚举类型的,注解类型的。

16、泛型入门示例代码:

Constructor<String> c = String.class.getConstructor(StringBuffer.class);

String str = c.newInstance(new StringBuffer("123"));

System.out.println(str);
之所以选取这个代码示例,是想说明泛型不仅可以用在集合中,也可以用在非集合中。类Constructor不是集合也拥有自己的泛型指定类型。

17、集合后的泛型限定供编译器使用,以挡住非法输入,编译通过后就只能去掉集合后的泛型限定。

18、泛型限定使集合中只能存储一种类型的对象,反射可以在该集合中添加不同类型的对象,示例如下:

ArrayList<Integer> al = new ArrayList<Integer>();
al.add(1);
al.add(2);
al.add(3);
System.out.println(al);//打印结果是:[1, 2, 3]

al.getClass().getMethod("add",Object.class).invoke(al, "abc");

System.out.println(al);//打印结果是:[1, 2, 3, abc]
19、参数化类型不考虑类型参数的继承关系

Vector<String> v1 = new Vector<Object>();
Vector<Object> v2 = new Vector<String>();
上述两行代码都是错误的。

20、创建数组实例时,数组元素的类型是不能使用参数化类型的。意思就是

Vector<String>[] v1 = new Vector<String>[3];
是不被允许的!

21、参数化类型与原始类型的兼容性

//原始类型引用可以接受一个参数化的类型
Vector v1 = new Vector<String>();

//参数的类型引用也可以接受一个原始类型
Vector<String> v2 = new Vector();
22、下述两行代码可以编译通过

Vector v = new Vector<String>();
Vector<Object> v1 = v;
原因是,编译器是一行行地编译的,单独一行不报错编译就不报错。

23、?为通配符,通配符可以设定上边界和下边界。

24、复习加泛型的应用:

a):Map.Entry
HashMap<String,Integer> map = new HashMap<String,Integer>();

map.put("zhangsan", 24);
map.put("lisi", 20);
map.put("wangwu", 29);
map.put("zhaoliu", 26);

Set<Map.Entry<String,Integer>> mapSets = map.entrySet();

for(Map.Entry<String,Integer> mapSet:mapSets )
{
System.out
.println(mapSet.getKey() + " : " + mapSet.getValue());
}
b):Iterator

HashMap<String,Integer> map = new HashMap<String,Integer>();

map.put("zhangsan", 24);
map.put("lisi", 20);
map.put("wangwu", 29);
map.put("zhaoliu", 26);

Set<String> keySet = map.keySet();
Iterator<String> it= keySet.iterator();

while(it.hasNext())
{
String str = it.next();
System.out.println(str+" : "+map.get(str));
}
25、

public static void main(String[] args) throws Exception {

add(1,2);
Number n = add(4.1,4);
Object obj = add(5,"123");

}
private static <T> T add(T a, T b)
{
return a;
}
上述代码可以编译通过!为什么可以通过呢?根据add方法来看,不应该是两参数应该是相同类型的吗?为什么不同类型的也可以编译通过呢?在遇到这种情况时,返回值T取的是传入的两参数类型的“交集”(意思就是,可以包含两参数类型的类型,比如说,传入两参数类型分别是Integer和Float,那么可以包含这两种类型的类型就是Number及其父类)。

26、泛型方法中的类型参数只能接受对象,而不能接受基本数据类型的数据。下面是示例:

public static void main(String[] args) {
swap(new String[]{"123","abc","789"},1,2);
swap(new int[]{1,2,3,4},1,2);
}
public static <T> void swap(T[] arr, int i, int j)
{
//这个函数的作用是交换给定数组的两个元素的位置

T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
第2个swap函数不能编译通过,第一个就可以。这验证了上面的观点,类型参数T只能够接受对象而不能接受基本数据类型的数据。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: