黑马java基础加强学习

1.MyEclipse Eclipse的一个插件

2.WorkSpace(工作间),一个工作间可以包含多个工程

3.切换工作间,文件目录—>Switch WorkSpace>other

4.Perspective(透视符)view(视图),在Eclipse运行的程序中,每一个小窗口就是一个视图,一个透视符可以有多个视图(例如:java透视符,debug透视符,MyEclipse透视符)

1.     jdk1.5提供了静态引入功能。引入的是后使用Import static 这样的关键字。

 

2.     java 重写和重载的概念和区别。

 

方法的重写Overriding和重载OverloadingJava多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。总结:简单点就是Overriding是两个类之间的事情,Overloading是一个类的事情。

 

3.     jdk1.5中加强for循环,可以直接通过for(对象:对象集合)这样的方式,来迭代对象集合中的对象。

 

a)       个人理解:这一个加强只能在默写方面提供了方便。比如我要想准确的知道迭代集合中的第几个时候需要做某些操作就完全控制不了了。

 

4.     jdk1.5制动的拆箱和装箱,一个非基本数据类型Intger 是不能执行加法运算的,但是1.5中可以直接编译和运行。这就是提供的这个功能的体现

 

5.     枚举类型:就是让某一个对象只能等于特定的几个对象时,就要使用枚举,比如说一个星期要从周日开始一直到周六,只有这么7个特定的条件,我们就要创建一个枚举类型。enum 是枚举的意思

 

6.     java的反射 Class 代表这一类事物。java.lang.reflect.* 。其中field是对Class所对应的字段或者说属性的操作。Class中,还提供了很多对Class类中的操作方法。Methodfield一样,但是他是对Class中的方法的一种操作。通过这些操作我们可以在runtime的时候,动态的解析一个未知的对象属性和方法,也可以动态的修改未知对象的属性值和执行它里面特定的方法。

 

a)       个人理解:通过这段反射的视频,确实让我收益很多。有的很多类原来不了解。想起原来自己想写一个小的持久化的框架,我就自己的一点点使用反射的技术取到字段的名字有在后台一点点的找寻属性的类型。最后要通过截取字符串来判断方法的名字。现在看来确实走很多的弯路当时。

 

7.     ArrayListHashSet的区别,在一般看来他们都是可以装各种对象的集合,其中ArrayList装载的集合是有序的,可以重复的集合。而HashSet是无序的,不可以重复的集合。这里需要特并强调的HashSet的存储方式,他是通过哈希值来判断,HashSet中是否有这个对象的。如果一个对象已经保存到HashSet中,后就不要再修改这个对象的值了。这样容易造成内存的溢出。因为哈希值的产生是要通过每个对象中的属性的值产生的,所以当保存在hashset以后再修改里面对象的值,就容易造成在hashset中无法再次找到原来的对象,造成内存的溢出问题。

 

a)    让我明白了内存溢出的含义,原来我一直在现java有垃圾回收机制内存问题是可以避免的,虽然在工作中,也明白尽量少去创建对象,更多的是使用内存中已经存在的对象还使用,但是有的时候在大数据量的情况下还是会有工程减慢或者效率比较地下的事情发生。

 

b)  HashSet这个对象,我原来一直用他来排除一个集合中重复的对象,但并不真正理解里面的含义。真的就像教程上说的,在hashSet总保存的对象修改以后我再去调用里面的对象,发现居然对象里面的值没有修改的事情,原来一直很费解,现在明白了为什么。

 

8.     JavaBean是一类特使的java类,它是按照一中规范来编写的。而这种规范被广泛的应用于java项目的开发过程中,所以,jdk提供符合这种规范的操作类。

 

9.     BeanUtils,是Apache公司给我提供的对javaBean对象的操作的支持包。但是这个包需要日志包的支持

 

 

 

 

数组的反射,

 1.具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class是你对象。

2.Class实例对象的getSuperClass()方法返回为Object类对应的Class.

3.基本类型的一维数组可以当Object类型使用,不能做Object[]类型使用;非基本类型的一维数组,既可做Object也可做Object[].

4.Arrays.asList()方法处理int[]String[]的差异,int[]类型的元素不是Object类型的,所以整个数组被当做了Object类型,而String[]类型的元素可以作为Object类型,所以可以被解析出来:

例如:

 int[] a1=new int[]{1,2,3};

 String[] a4=new String[]{"a","b","c"};

 System.out.println(a1);                     System.out.println(a4);

 System.out.println(Arrays.asList(a1));

 System.out.println(Arrays.asList(a4));

 结果为:[I@1d5550d

         [Ljava.lang.String;@c2ea3f

         [[I@1d5550d]

         [a, b, c]

二十六:

 

  ArrayList:是有序的集合,把对象的引用放入,而不是放入对象,每放一次就会多一个引用变量,就会按顺序往后排,

HashSet:放入时候先判断集合里有无对象,如果有就不放,想放就把以前的删掉,没有就放

 

public static void main(String[] args) {

        //Collection collections=new ArrayList();

              Collection collections=new HashSet();

              ReflectPoint pt1=new ReflectPoint(3,3);

              ReflectPoint pt2=new ReflectPoint(5,5);

              ReflectPoint pt3=new ReflectPoint(3,3);

             

              collections.add(pt1);

              collections.add(pt2);

              collections.add(pt3);

              collections.add(pt1);

              //ReflectPoint中的hashcode去掉,可能是3,也可能是2

//如果不ReflectPoint中增自定义的equals方法,输出的结果就是4,增加了就可以比较傲pt1pt3相同了,输出结果就是3

              System.out.println(collections.size());

       }

 

HashCode方法的作用:哈希算法,采用对某个数字n进行取余的方式对哈希码进行分组和划分对象的存储方式,在每个区域内查找,可以提高效率

 

经验:当一个对象存储进hashSet集合中以后就不能修改这个对象中的的那些参与计算哈希值的字段了,否则将和以前的不同,会导致内存泄露

 

 

 

二十七。

反射的作用:实现框架的功能

框架:别人用你的类,你用别人的,归根到底都是你在用别人的类.例如:房子是我买的,是框架,而锁,门窗就是我的类......框架就是“半成品”

 

写一个配置文件,这样就可以作为反射了,别人在用这个框架时候,就可以修改配置文件了

 

配置文件config.properties的内容:

   className=java.util.HashSet

 

代码:InputStream ips = new FileInputStream("config.properties");       

Properties props = new Properties();            props.load(ips);

ips.close();

String className=props.getProperty("className");

Collection collections =(Collection)Class.forName(className).newInstance();

//                   Collection collections = new HashSet();

                     ReflectPoint pt1 = new ReflectPoint(3, 3);

                     ReflectPoint pt2 = new ReflectPoint(5, 5);

                     ReflectPoint pt3 = new ReflectPoint(3, 3);

collections.add(pt1);

collections.add(pt2);

collections.add(pt3);

collections.add(pt1);

System.out.println(collections.size());

 

 

二十八:

getRealPath();得到硬盘上的位置,得到总的目录

一定要用完整的路径,当完整的路径不是硬编码,而是运算出来的.

 

.class文件都要加载到内存中—类加载器

只要运行这个类,字节码就加载到内存中

 

如:

//类加载器,配置文件都是放在classpath指定的目录下

                     //InputStream ips=ReflectTest2.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");

//config.properties的路径是相对于我的包的路径来的

                     InputStream ips=ReflectTest2.class.getResourceAsStream("config.properties");

//绝对路径

                     InputStream ips=ReflectTest2.class.getResourceAsStream("/cn/itcast/day1/resource/config.properties");

 

二十九:

内省(IntroSpector:体验、检查),主要用于对javaBeanjavaBean:特殊的java类,它里面的方法按某种规则起名)进行操作。

如果第一个字母是小写的,则把第一个字母变成小的

 

 

31.IntroSpector.getBeanInfo方法,

内省的方式对javabeangetset属性设置

 

 

  32.Beanutils设置java属性和读取java属性

 

可以吧javabean的属性转变成Web

map{age:7,name:"xyb"}

 

 

33. 注解,annotation,是一种标记,加上注解就相当于告诉虚拟机的一种标记。然后通过反射就可以通过注解去了解你的这个方法,这个类,这属性的信息,然后去做相关的操作。注解标记可以应用在包,类,属性,方法,以及方法的参数上,在java.lang包中可以看见基本注解一共有3种。

 

a)        注解annotation是这样定义的

 

注解中的属性,定义方式和普通类中的方法很类似。

 

import java.lang.annotation.ElementType;

 

import java.lang.annotation.Retention;

 

import java.lang.annotation.RetentionPolicy;

 

import java.lang.annotation.Target;

 

 

 

/*

 

 * 这个注解叫源注解,

 

 * 一个注解是有3个阶段,

 

 * 一个是在源文件阶段,一个实在Class文件阶段,还有一个是在运行时阶段。

 

 * 所以,我们自定义的注解就要告诉编译器,我们的注解要保留到那个阶段。

 

 * 默认的实在Class阶段

 

 *

 

 */

 

@Retention(RetentionPolicy.RUNTIME)

 

@Target({ElementType.METHOD,ElementType.TYPE})

 

public @interface ItcastAnnotation {

 

       String str() default "a";

 

       String value() ;

 

       int [] arrayattr() default {1,2,3};

 

       Week w() default Week.E;

 

       Shouji j() default @Shouji("sanxin");

 

       @SuppressWarnings("unchecked")

 

       Class clzz();

 

}

 

b)       个人理解:注解中的属性,可以是基础类型,也可以自定义类型。也可以是枚举类型,还可以是注解类型,甚至是Class类型的。其中Retention这个注解,是告诉虚拟机,我的自定义的注解要保存在运行时的,而target注解是规定自定义注解的使用范围。

 

c)        个人理解:我对注解的一点个人理解,注解的作用就是让我们在不使用java 反射的情况下,就能知道Class类的相关信息,因为java的反射很影响工程或者项目的效率。甚至,在自定义的注解中,我们可以取代一些框架的配置文件的作用。实现工程中全部都是类,没有其他文件。

 

2.     java泛型:ArrayList<String>ArrayList<Intger>在编译以后使用的是同一份字节码。(也就是说,通过java 的反设,可以穿过泛型,给工程可能带来未知的错误和异常)。

 

a)        泛型术语:整个成为ArrayList<E>泛型类型

 

b)        ArrayList<E>中的E称为类型变量或类型参数

 

c)         整个ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数

 

d)        ArrayList<Integer>中的<>typeof

 

e)         ArrayList称为原是类型。

 

3.     java中泛型中的通配符 在泛型中的类型参数不能考虑子类父类关系。在使用通配符的对象中,就不能使用该对象一切,涉及到对象类型的方法。通配符的扩展,Vector<? Extends Number> x = new Vector<Integer>();这个说明?的类型参数在Number的这个范围里面。只要在Number的范围中就可以。另外的一种是Vector<?    Super Integer> x =new Vector<Number>();这个说明,必须是Integer上面的包里面的都可以。

 

泛型的小例子:package com.day2;

 

 

 

import java.util.HashMap;

 

import java.util.Map;

 

import java.util.Set;

 

 

 

@ItcastAnnotation(clzz=AnnotationTest.class,value="str",j=@Shouji("moto"))

 

public class AnnotationTest {

 

 

 

   /**

 

    * 循环一个Map

 

    */

 

   public static void main(String[] args) {

 

      // TODO Auto-generated method stub

 

HashMap<String,Integer> maps

 

=new HashMap<String,Integer>();

 

      maps.put("tianzhw", 26);

 

      maps.put("shangdi", 100000);

 

      maps.put("laji", 999999999);

 

      Set<Map.Entry<String, Integer>> setEntry=maps.entrySet();

 

      for(Map.Entry<String, Integer> entry: setEntry)

 

      {

 

System.out.println(entry.getKey()

 

+ ":" + entry.getValue());

 

      }

 

     }

 

}

 

   Map的集合中,都是键值一一对应的。其实Map中每一个键值都是一个Map.Entry对象。定义一个HashMap的泛型其实就是定义了MapEntry对象的泛型。然后通过迭代方法,得到Map中的键值对应。

 

4.     自定义泛型 public <T extends Map> T abc() 这样的定义了一个类型T,同时也说明了TMap的子类。

 

a)        泛型的定义中,不能有基本类型做为参数。

 

对于泛型的集合和自定义泛型集合,我没有能够有太多的理解,只是知道如果定义一个自定义的类型。如何限制它的范围。但通过泛型这节课我对泛型的理解更加深刻和系统

1.    了。

 

2.     定义累计别的泛型,public class test<T>这样定义,这样定义以后整个类中的泛型就统一了。

 

3.     通过反射去知道泛型集合的里面的类型参数,通过对象是不能实现的。要通过方法才能知道这样的集合中泛型的类型具体是什么,代码的编程思想是,现通过java的字节码获取某一个方法的Method,然后可以获得Method,以泛型的方式获得参数类型。这样,我们就可以获得参数类型和实际参数类型了。通过这个方法很多这个框架实现了自动的封装JavaBean的功能。

 

 

 

40.Java的动态代理proxy和面向切面的编程

 

能够实现动态代理的类,一定是实现了某一个接口的类。什么面向切面的编程,其实就是为我们日常的类创建一个代理类通过代理类,再通过代理类来调用我们的日常类。在代理类中,我们执行一些固定的代码

 

如果我们要通过代理类,来执行一些固定的操作,其实就是在目标类执行之前,执行之后,我们要添加一些固定的操作。这些操作固定而且是如果正常写入目标类中,重复性很强。但是我们又不清楚,每一个前面执行的具体流程所以。使用代理类。所以,我们要先指定一个规范,来告诉代理类,我们是按照什么规范来写的固定特殊业务。所以我们要创建规范的接口,代理类就是实在执行目标之前和之后来执行,固定的接口方法。而接口的实现,要根据业务的实际需求来确定。

 

 

例子说明:

 

package com.proxy;

 

 

 

public class test implements MyTest {

 

   /* (non-Javadoc)

 

    * @see com.proxy.MyTest#okTest()

 

    */

 

   public String okTest()

 

   {

 

      System.out.println("this is okTest()");

 

      return "OK hahaha";

 

   }

 

  

 

   /* (non-Javadoc)

 

    * @see com.proxy.MyTest#gInt(int)

 

    */

 

   public int gInt(int i)

 

   {

 

      System.out.println("this is gInt(int i)");

 

      return i+100;

 

   }

 

}

 

package com.proxy;

 

 

 

public interface MyTest {

 

 

 

   public abstract String okTest();

 

 

 

   public abstract int gInt(int i);

 

 

 

}

 

 

package com.proxy;

 

 

 

public interface Advice {

 

   void beMethod();

 

   void afMethod();

 

}

 

同时创建规范接口实现类

 

package com.proxy;

 

 

 

public class AdviceImpl implements Advice {

 

 

 

   public void afMethod() {

 

      // TODO Auto-generated method stub

 

      System.out.println("afMethod");

 

   }

 

 

 

   public void beMethod() {

 

      // TODO Auto-generated method stub

 

      System.out.println("beMethod");

 

   }

 

 

 

}

 

这个时候我们创建代理类

 

package com.proxy;

 

 

 

import java.lang.reflect.InvocationHandler;

 

import java.lang.reflect.Method;

 

import java.lang.reflect.Proxy;

 

 

 

public class TestProxy {

 

              public Object getProxy(final Object target, final Advice advice) {

 

              return Proxy.newProxyInstance(target.getClass().getClassLoader(),

 

                            target.getClass().getInterfaces(), new InvocationHandler() {

 

                                   public Object invoke(Object proxy, Method method,

 

                                                 Object[] args) throws Throwable {

 

                                          advice.beMethod();

 

                                          Object obj=method.invoke(target, args);

 

                                          advice.afMethod();

 

                                          return obj;

 

                                   }

 

                            });

 

       }

 

 

 

}

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值