Skip to content

lessons

Miguel Gamboa edited this page Mar 16, 2023 · 28 revisions

Lessons:


Bibliography - The Well-Grounded Java Developer, Second Edition:

  • 1.1 - The language and the platform
  • 1.2 - The new Java release model
  • 4.1 - Class loading and class objects
  • 4.2 - Class loaders
  • 4.3 - Examining class files
  • 4.5 - Reflection
  • Bibliography and Lecturing methodology: github and slack.
  • Tools: javac, javap, kotlinc, JDK 17 and gradle.
  • Program outline in 3 parts:
    1. Java Type System and Reflection;
    2. Metaprogramming and Performance;
    3. Iterators versus Sequences (yield). Generics and Reified type parameters.
  • Project in 3 parts according to program outline.

  • Managed Runtime or Execution Environment.
  • Informally virtual machine (VM) or runtime
  • Historic evolution since Java to nowadays
  • Examples of languages targeting JVM: Java, kotlin, Scala, Clojure.
  • Examples of languages targeting Node: JavaScript, TypeScript, Kotlin.
  • Java syntax similar to C and C++.
  • Distinguish between Programming Language <versus> VM
  • Type System - Set of rules and principles that specify how types are defined and behave.
  • Module .classfor each class definition
  • CLASSPATH
    • e.g. -cp . - local folder
    • e.g. -cp .:JetBrains/IntelliJIdea2022.2/plugins/Kotlin/lib/*
    • (for windows use ; rather than :)
  • Class have Members
  • Members may be: Fields, Constructors or Methods.
  • Constructor is a function with name "<init>" returning void.
  • Using javap -p Student.class to inspect metadata
  • Using javap -c -p AppKt.class to inspect metadata and bytecodes definition of data class Point
  • Analyzing kotin properties in Java.
  • There are NO properties in Java Type System.
  • A Kotlin property may generate:
    • Backing field -- accessed with getfield bytecode.
    • Getter, i.e. function get... -- called with invoke... bytecode.
    • Setter, i.e. function set... (if defined with var).
  • Kotlin val <=> Java final.
  • FIELDS => MEM
  • bytecode invokevirtual to call e.g. getNr() and print()

  • Component - Reusable software unit, with:
    • IR - code in intermediate representation (e.g. bytecodes, IL, other)
    • Metadata - auto description
    • Ready to use => does not require static compilation.
    • API => conforms to a public interface.
    • Indivisible => 1 module (file)
  • Software development by Components:
    • Reduce Complexity;
    • Promote Reuse.
  • Developer roles:
    • Provider - provides a component with a well-known API (e.g. Point)
    • Client - uses the component from a provider to build an Application, or another component (e.g. App).
  • Managed Runtime:
    • Software components = Metadata + IR (intermediate representation) (e.g. bytecodes)
    • Interoperability supported at bytecode and metadata level e.g. Java <> Kotlin
    • Portability - Compile once and run everywhere with VM, e.g. JRE.
    • Jitter - Just-in-time compiler
    • Safety - NO invalid memory accesses
    • GC - Garbage Collector.
    • ClassLoader and CLASSPATH - dynamic and lazy load.
  • Homework 01 resolution
  • Java Type descriptors
  • Java access control
  • Immutability through final fields equivalent to kotlin val
  • Virtual and non-virtual methods (Kotlin open versus Java final )
  • Optional @Override annotation in Java equivalent to kotlin keyword override
  • Java static members
  • Translating kotlin companion objects to Java
  • Translating kotlin extensions to Java
  • Unmanaged <versus> Managed
  • Static <versus> Dynamic link

  • Building unmanaged components with static link:
    • NOT a unit, but two parts instead: header + obj
    • Need of a header file that describes the component content
    • Different builds for different architectures
    • Structural modifications (new header) => compilation + link
    • Behavioral modifications => link
  • Demo with an unmanaged App using a Point.
    • Static compilation (gcc -c) and static link (gcc)
  • Demo with a managed App using a Point.
    • Jitter (just-in-time compiler) - compiles IR to native code (e.g. x86, amd64, ppc) at runtime
    • Dynamic link - Point.class on App compilation + link at runtime.
    • Lazy Load - Point.class is loaded only when needed
  • Homework 02 resolution
  • Translating kotlin companion objects to Java
  • Java static nested classes e.g. class Person { static class Companion { .. }} => Person$Companion
  • Java static constructor
  • Singleton design pattern
  • Private instance constructor to avoid new objects.
  • Translating kotlin extensions to Java.

  • Reflection object oriented API for metadata

  • KClass is representing a type in Kotlin, whereas Class is representing a type in JVM.
  • KClass --- .java ---> Class
  • Class ---- .kotlin ---> KClass
  • TypeName.class - returns the Class corresponding to the type TypeName.
  • refObject.getClass() - returns the Class of the object referenced by refObject.

  • Java Reflection API (java.lang.reflect): Class, Member, Field, Executable, Constructor, Method and Parameter.
  • Inspecting functions trough Reflection API
  • Method => Class<?> getReturnType(); Parameter[] getParameters();
  • Parameter => Class<?> getType() - the declared type for the parameter represented by this Parameter.
  • Field => Class<?> getType() - the declared type for the field represented by this Field.
  • NOTICE do not mislead getType() with getClass()

  • Invoking methods and creating instances:
  • Method => Object invoke(Object obj, Object... args)
    • Invokes the underlying method represented by this Method object, on the specified object obj with the specified parameters args.
  • Check if a method is static - Modifier.isStatic(m.getModifiers())
  • Constructor => T newInstance(Object... initargs)
    • Uses the constructor represented by this Constructor object to create and initialize a new instance of the constructor's declaring class, with the specified parameters initargs.

  • ClassLoader - class-loading capability exposed to the user programmer.
    • BootstrapClassLoader - used to get the absolute basic system loaded—essentially java.base.
    • AppClassLoader - loads the application classes in CLASSPATH.
    • UrlClassLoader - loads classes and resources from a search path of URLs.
  • Example
static Stream<Class<?>>listClassesInClasspath() throws IOException {
    ClassLoader cl = ClassLoader.getSystemClassLoader();     // An AppClassLoader instance
    return list(cl.getResources("")).stream()
            .filter(url -> url.getProtocol().equals("file")) // Exclude jar files
            .map(url -> new File(toURI(url)))
            .flatMap(f -> f.isDirectory() ? stream(f.listFiles()) : Stream.of(f))
            .filter(f -> f.getName().contains(".class"))
            .map(f -> loadClass(cl, qualifiedName(f.getName())));
}
  • Homework 03 resolution

  • Distinguishing between streams of java.io and java.util.stream.
  • java.io streams are related with implementations of InputStream and OutputStream.
  • java.util.stream provides abstractions on sequences and its operations like filter, map, reduce, etc.

  • Type check, e.g. if m is compatible with Method:
    • m instanceof Method => true if m is an instance of the class Method or any inherited class.
    • m.getClass() == Method => true if m has exactly the type Method.
  • get<member> versus getDeclared<member> to get inaccessible members (e.g. private).
  • setAccessible(boolean) => to invoke inaccessible methods or constructors (e.g. private)
  • Distinguishing the role of App domain ---> Logger utility.
  • Unit tests with sample domain Student and Point
  • Simple Logger ---> Printer
  • Decouple Logger output into a Printer interface.
  • Implement PrinterConsole and PrinterBuffer.
  • Make PrinterConsole singleton.
  • logFields(Object target)
  • logProperties(Object target) - for parameterless methods with get prefix and non void return type.

Clone this wiki locally