0x150
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Reified generics solve this problem, but they're not supported in java yet.
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
This isn't exactly foolproof, since you can technically pass an array to the method manually and use some other type extending T, but it's the best method we have right now.
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Generic types are placeholders for reference types that can be used to make a piece of code work for multiple types, without having to duplicate the code. They're like C++'s templates, although less advanced. Whereas C++'s templates are literal templates that just insert the type (or value) used in the generic type parameter, Java figures out the types at compile time. The resulting bytecode then uses the first parent type applicable to all possible types of the generic type, and can safely cast that parent type to the used generic type based on usage.
this will be compiled to:
but due to compile time constraints, javac can safely transform usages of the code like
to
.
Doing it this way means that basic generic types are supported, but this also means that type information about a generic type can't be accessed at runtime, since the generic type doesn't really exist at runtime anymore. A hack is using an automatically filled vararg parameter with the generic type you want to test, such as:
because this method can be called like
this.<String>printTheGivenType()
, without passing the vararg parameter explicity, javac will generate an empty array of T, and pass it to the method, which looks like this at runtime: printTheGivenType(new String[0])
. With that information, we can figure out which type the array has, and can thus figure the type out.15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
This small example shows how a generified type can be used:
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
For instance, the aforementioned
java.util.List
interface defines a single generic parameter, <T>
. Most of the methods in the interface make use of this generic parameter for their own arguments and/or return type.15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
However, generics allow types and methods to define one or more generic parameters. The compiler uses these to constrain the the types of parameters or return values that are allowed at a call site or within a method.
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Obviously, number 2 is not practical (and may not even be possible). So, before generics, the
List
interface operated on Object
. This works, but is not type-safe. There is nothing preventing someone from inserting a String
into a list that is expected to contain Integer
s. This would actually work on the add
call. But down the road, when objects are read from the list, the client would have no way of knowing whether the objects it retrieves are Integer
s or something else, without checking every time.15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
The classic use case for generics are collections of objects. As an example, think about the
java.util.List
interface. Without generics, there would be only 2 possibilities for the API:
1. Methods like add
and get
would operate on Object
, so that any possible object could be passed/returned
2. Methods like add
and get
would need to be overridden for every possible class15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Generics are a language feature that was added to Java 5. They allow code to work with objects of any type (or a constrained type), rather than a single specific type.
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Generics is used for type templating where the return type of a method can be different types or class uses different types of members. My favourite example of a good usage of generics is with Transformers or a Provider or List. You're welcome ( ̄︶ ̄)↗
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Generics enables developers to define functions, classes, and interfaces that can work with multiple data types, without the need for explicit type casting or separate implementations for each type. Example
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Wildcards can be specified using the
?
-symbol meaning "any fixed type" whereas ? extends Temporal
refers to "any fixed subtype of Temporal
". It is also possible to use the super
keyword to specify bounds requiring a supertype.
Generics can have bounds specifying that the types must be within these bounds.
These bounds can also make use of wildcards. For example, it is possible to require a generic type to extend Collection
of some Temporal
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Methods can also declare generic types by specifying them before the return type:
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/22/2024 in #❓︱qotw-answers
Week 105 — What are generics and how can they be used?
Generics allow specifying placeholders for types in classes and methods.
If a class specifies a generic/type parameter using the
<T>
syntax, it can use the type T
for variables, parameters, return types and superclasses/interfaces.
When an object of that class is created, all generics should be assigned to concrete types. Generics cannot be assigned to primitives (as of JDK 23 which is the current Java version at the time of writing this).
15 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/15/2024 in #❓︱qotw-answers
Week 104 — What options are there for logging information in Java applications?
Third-party logging frameworks also exist, and can provide advantages over the JDK's logging facilities. Log4J and Logback are two of the more popular ones. SLF4J (Simple Logging Facade for Java) is also an interesting option. It provides a common facade, along with adapters, for working with other logging frameworks, including
java.util.logging
.7 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/15/2024 in #❓︱qotw-answers
Week 104 — What options are there for logging information in Java applications?
The
java.util.logging
package is a logging framework built directly into the JDK (for JDK 9+, the JDK module java.logging
is required). There are 3 main components -- Logger
, Handler
, and Formatter
.
Loggers are the component that client code typically works with. Applications use them to send log messages into the logging subsystem. Each message has a level associated with it. The level is hierarchical, and allows the verbosity of the log messages to be controlled at runtime. For instance, if the logging system is set to INFO
, then only messages at the SEVERE
, WARNING
, or INFO
levels will be output to the log; messages at CONFIG
or lower will be suppressed.
Handlers provide a destination for the log messages. For instance, the ConsoleHandler
will direct messages to System.out
or System.err
. Multiple handlers can be configured, each with their own settings, and the subsystem will take care of sending each log message to all applicable handlers.
Formatters are attached to handlers and control the format of the log messages. In addition to the log message from application code, formatters can add metadata like the timestamp of the message, the level, etc. They can even output the message in special formats such as JSON or XML.7 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/15/2024 in #❓︱qotw-answers
Week 104 — What options are there for logging information in Java applications?
The most basic option for logging is simply writing to
System.out
and System.err
. However, anything more than a trivial application will want to make use of a proper logging framework.7 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/15/2024 in #❓︱qotw-answers
Week 104 — What options are there for logging information in Java applications?
7 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/15/2024 in #❓︱qotw-answers
Week 104 — What options are there for logging information in Java applications?
you can use the native logging library (java.logging.Logger)
7 replies
JCHJava Community | Help. Code. Learn.
•Created by JavaBot on 12/15/2024 in #❓︱qotw-answers
Week 104 — What options are there for logging information in Java applications?
The easiest way to log data is to use
System.out
which normally forwards everything to the console associated with the application (stdout and stderr for System.err
).
However, this does not allow specifying log levels and cannot be configured apart from redirecting it to a different PrintStream
or by redirecting stdout for the entire application and does not differentiate between log levels/severities.
Because of this, the java.util.logging
package in the java.logging
module has been introduced.
These loggers can be configured in a logging.properties
file which can be specified using the java.util.logging.config.file
parameter.
Other than that, SLF4J (Simple Logging Farcade for Java) provides a general API that can be used with many different loggers. To use the API, one needs to add the slf4j-api
dependency.
When an SLF4J logger implementation dependency like logback is added at runtime, these messages will be logged using that dependency.7 replies