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

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只能够接受对象而不能接受基本数据类型的数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值