Let's say I want to write isSubdirectory static function in my FileUtils helper class. This function would look like:
class FileUtils {
public static boolean isSubdirectory(File child, File parent) {
// ...
}
}
Or I could flip parent and child parameters:
class FileUtils {
public static boolean isSubdirectory(File parent, File child) {
// ...
}
}
And I cannot choose which order is right...
In Kotlin there would not be any doubts: just declare extension function:
fun File.isSubdirectory(parent: File) {
// ...
}
With an eye on kotlin I have invented mnemonic rule: first parameter in static function should be considered as this (I'm not the first who invented this rule. I saw many people also using it). So in this example I'd prefer placing child as first parameter.
But the question is: is this rule is already formalized and has well known name? I've tired to repeat this rule to people who don't know it and I wish I could simply refer to this rule by it's name.
I'm not sure that there's a name or any real formalization. At best, it's just a common convention to have the first parameter look like the this.
Although rarest, the "this last" convention also exists, more in C and early C++ (Example: stdio with fread/fwrite)
There also exist conventions based on the argument type; for example promoting the following order:
Collection and other objects with generic parameters
Arrays of objects
Objects without generics
String
Arrays of primitive types, e.g. byte[]
double, float
long, int, short, byte
boolean
There also exist the more or less exact opposite order. Other conventions also tend to group arguments by their type, prefering method(String, String, int, int) rather than method(String, int, String, int).
As you can see, there are a lot of conventions that exist. I'm not sure that any of them has a name, and that any is really much more used than any other.
It isn't as clear as camelCase vs. snake_case for example, which almost no one contradict.
What you can keep from all that is the following: put the arguments in the order that looks the most logical and straightforward to you.
The most important is to stay consist in the entire project, i.e. don't write isFileX(a,b) and then isFileY(b,a) for example, a fortiori if the two methods are in the same class.
IN case of doubt, don't hesitate to ask other people working on your project what they think is the best.
For your particular case, it's reasonnable to put child first because of the "this first" rule, but it's as reasonnable to put the parent first, as it's also a common convention for example in GUI frameworks.
It's up to you to decide.
Related
Let's say I want a method to modify 2 Strings (or any other immutable class), I can't return a single object. So I can pass a List, String[] or 2 AtomicReference objects. Each of these has downsides. Lists and arrays don't allow naming of each of the parameters, and we're relying on the order of the elements to ensure the right Strings are set. AtomicReference is intended atomic updates so it does way more than what I need it to do. I simply need something like this:
public class Reference <T> {
private T value;
public T get() {
return value;
}
public void set(T value) {
this.value = value;
}
}
I would think a class like this is available in some Apache library or Spring library, but I couldn't find anything like this. I would think this is a pretty basic need for many developers, so is it in some 3rd party library that I'm not aware of?
This mostly applies to the case of 2 or 3 objects. When there are >3 immutable objects, I might create a new class just to hold these references.
I'm also aware of Apache Pair and Triple, but they have the same issue as List, where I can't name the parameters.
If you want the "named tuples" to be immutable, the best fit for your requirements is a Java 14+ record class. Essentially, it is a lightweight class that is roughly analogous to a C / C++ struct .... but immutable;
When you need the "named tuples" to be mutable (or if Java 14+ is not an option for you yet), there two alternatives:
If the "field" names are dynamic, then you can use a Map. Any Map implementation will do. There are problems with this:
You must use m.get(name) and m.put(name, value) syntax.
The compiler cannot check that you are using the correct name strings.
The values all need to be the same type, or have the same base type. If the "fields" have different types, you will need to use type-casting; e.g. from Object to the expected type.
If the "field" names are static (i.e. you want to be able to refer to them as Java identifiers, the only alternative is to declare a conventional class. It could be an "unencapsulated" class; e.g.
public class Things {
public Type1 thing1;
public Type2 thing2;
}
The fields could be declared as final and then you will need to
declare a constructor.
While it is good style to have getters, setters and a constructor, the Java language doesn't force you to do declare and/or use them. You just need to understand the consequences of ignoring encapsulation. (And be able to cope with the negative code reviews ...)
For what it is worth, you cannot design a library class where the names of your fields are regular parameters or type parameters. (Or at least, not in a way that can be used by conventional Java code; e.g. using x.name or x.getName().) That's why you can't find one!
I was searching for any ways to check whether the type of the given attribute of a class is of custom object type (for eg., Person) or Java object (for eg., String, Long, primitive types as well) type. If instanceof is used, it will be hectic checking all of the Java types. Can anyone suggest a way to check, if anything as such exists.
Java is very much "built on itself". Much of the SDK could be considered both "custom" or "built-in" depending on which way you are looking at it.
For instance, Exception is built in to Java but also written in Java. You could write similar code yourself, however based on what you've said I am guessing you would consider it a "Java object".
Similarly, ArrayList is also written in Java, but because it's a utility class, I'm guessing you would consider it "custom", though I'm not sure, since it is still included in the SDK.
Without knowing exactly what you are looking for, the closest grouping that I can guess based on what you've said (String, Long, etc.) is the java.lang package. In the words of the SDK documentation itself, the java.lang package:
Provides classes that are fundamental to the design of the Java programming language.
You can check if the package name of the class for the object is in java.lang:
static class A {
}
public static void main (String[] args) {
String test1 = "";
A test2 = new A();
int test3 = 3;
System.out.println(isJavaLang(test1));
System.out.println(isJavaLang(test2));
System.out.println(isJavaLang(test3));
}
public static boolean isJavaLang(Object check) {
return check.getClass().getName().startsWith("java.lang");
}
Working example
There's no fail-safe method to do this. As others said, Java builds a lot on regular classes.
I guess that, appart from primitives, it all boils down to your own definition of "JDK's classes" vs "my classes" vs "3rd party classes".
#splungebob's solution works for your own, single tree-branch classes.
I would think that classes from the following packages can be safely, if minimallistically, regarded as JDK's:
java.lang.*
java.*
javax.*
com.sun.*
com.oracle.*
You might also add some common 3rd parties like org.apache.*
Try maybe using implementation vendor title of package that object is coming from. It seems that standard Java packages have this value set to "Oracle Corporation". "Java Runtime Environment".
public static boolean isJavaLang(Object check) {
if (check == null)// lets say that null comes from JRE
return true;
return isJavaLang(check.getClass());
}
public static boolean isJavaLang(Class<?> check) {
Package p = check.getClass().getPackage();
if (p == null) // default package is package for users classes
return false;
String title = p.getImplementationTitle();
if (title == null)// no title -> class not from Oracle
return false;
// System.out.println(p.getImplementationVendor());
// System.out.println(p.getImplementationTitle());
return title.equals("Java Runtime Environment");
}
I'm not entirely sure I got your question right...
The java.lang.Class class features some tools you can use.
The isPrimitive() function
Determines if the specified Class object represents a primitive type.
There are nine predefined Class objects to represent the eight primitive types and void. These are created by the Java Virtual Machine, and have the same names as the primitive types that they represent, namely boolean, byte, char, short, int, long, float, and double.
These objects may only be accessed via the following public static final variables, and are the only Class objects for which this method returns true.
As for the other classes, there is no such thing as a "Java object" - every object is a Java object... But you could for example check if the name of the class in question begins with java.lang. prefix, but the java.lang package contains a lot different things too, not only the basic datatypes you'd like to find.
I think you want something like:
public static boolean isJavaObject(Object obj)
{
return (! obj.getClass().getName().startsWith("my.package"));
}
where "my.package" is the head of your package heirarchy.
Suppose that your own classes aren't located within packages whose names start with java*:
public static <T> boolean isJDKClass(T t) {
return t.getClass().getPackage().getName().startsWith("java");
}
Hi all I was wondering if I could modify and recompile a Java base class?
I would like to add functions to existing classes and be able to call these functions.
For example, I would like to add a function to java.lang.String, recompile it and use it for my project:
public char[] getInternalValue(){
return value;
}
I was wondering how do we go about doing that?
What you're referring to is called "monkey patching". It's possible in Java, but it isn't advisable and the results can be... uhh interesting. You can download the source for the String class, pop it into a JAR and prepend the bootclasspath with:
-Xbootclasspath/p:MonkeyPatchedString.jar
to replace the built-in String class with your own.
There's an interesting paper on this very subject here.
If you do it, you get incompatible with the java.lang.String class, and with all classes, relying on java.lang.String, which is very, very rarely a good idea.
A second problem could be the license. For self-studying it is perfectly fine, but if you publish your code (compiled or in source) you should read the license terms carefully before.
Since the String class is declared final, you can't even inherit from String, and implement your PacerierString, which seems useful at first sight. But there are so many people, who would have implemented their little helpers, that we would get a lot of SpecialString classes from everywhere.
A common practice would be people, writing a class Foo, and adding a method
public Foo toFoo () {
// some conversion for String representation of Foo
}
to their UniversalToolString.
You may, however, write a Wrapper, which contains a String. You might not pass your Wrapper to a method, which expects a String, but you would need to call its 'toString ()' method, if that happens to be a good candidate for that purpose.
Foo foo = new Foo ("foobar", 42);
foo.setMagic (foo.toString ().length);
Don't do that.
If you want to be evil, you can use reflection to access the byte array of a string. But of course there's no guarantee that that field will exist in the future as is... ok, it probably will, but caveat emptor.
I know well, what is a class literal in java, I just wonder, what is the reason for the .class in the syntax. Is there any ambiguity removed by this? I mean, wouldn't an alternative Java syntax using
Class<String> c = String;
instead of
Class<String> c = String.class;
work? To me the class keyword looks like a boilerplate.
Sure, you could make that the syntax. But using the .class suffix makes the compiler's job easier; it has to do less work to know that the code is syntactically correct.
Without the suffix, the compiler would have to work harder to understand the difference between this:
String.getName() // a method inherited from java.lang.Class<T>
and this:
String.valueOf(...) // a static method from java.lang.String
If you don't think that the .class suffix is needed, do you also think that the f and L suffices are useless (for float and long literals, respectively)?
It's just not the same thing. String is a class of type string, and String.member is one of its member variables, String.method() would be one of its methods.
String.class is an object of type Class that defines String. It seems a lot more intuitive that you need to specify .class to indicate that you're trying to refer to an object of type Class.
Not to mention that it's easier to parse this kind of construct, and potentially prevents bugs where you're accidentally returning a Class object when you didn't mean to.
This is even more relevant when you're looking at inner classes, like OuterClass.InnerClass.class.
To work with Matt's example: How would you work on the class object without having to create a temporary variable first? Assuming your class Foo has a static method called getClasses, how would you differentiate between Foo.getClasses and Foo.class.getClasses?
String is the String class pseudo-object which provides access to the classes static fields and methods, including class, which refers to the Class instance which describes the String class. So they are distinct, but because Java doesn't have the metaclass arrangement of (say) Smalltalk-80 this isn't very clear.
You could certainly make String and String.class synonymous if you wanted to, but I think there is a valid basis for the distinction.
Let's use integer as an example:
Class<Integer> c = Integer; // your proposal
int i = Integer.MAX_VALUE; // compare with below
int j = c.MAX_VALUE; // hmm, not a big fan, personally
It just doesn't seem to flow, in my opinion. But that's just my opinion :)
I have long java class and method names
LONGGGGGGGGGGGGGGGClass.longggggggggggggggggggggggggMethod();
I want to alias it to
g.m(); in another class
can this be done?
No.
Wrap it in a method with a name you like better.
For one thing, you should rarely be typing the class name. You might have something like this:
import DamnLongPackageNameThatIDontLikeTyping;
class MyCoolClass()
{
DamnLongClassNameThatIDontLikeTyping dlc=new DamnLongClassNameThatIDontLikeTyping();
dlc.this();
dlc.that();
dlc.tOther();
dlc.damnLongAnnoyingMethodNameStillHasToBeTypedEveryTime();
}
Okay, so that's not great, but you shouldn't be typing the entire class name very often, just when you first declare it; and the package import makes it so you don't have to type: DamnLongPackageNameThatIDontLikeTyping.DamnLongClassNameThatIDontLikeTyping every time.
Still, that can be annoying to type. Enter the editor. If you aren't using Eclipse, Netbeans or IntelliJ then you really need to stop reading right now and go install it--load up your project. I'll wait....
Seriously. Go get it. The rest of this won't be any fun without it.
Now, the really neat thing is that to get what I typed above, you just do this:
class MyCoolClass()
{
DLC<ctrl-space>
After typing that, your file will look like this:
import DamnLongPackageNameThatIDontLikeTyping;
class MyCoolClass()
{
DamnLongClassNameThatIDontLikeTyping<your cursor here>
Note that you didn't type damn long ANYTHING, just DLC It figured out what class you wanted to import, added an import for it and stuck the class in there. (You may have to choose from a list of classes if there is more than one match).
On top of that, once you have an object named dlc instantiated you can type:
dlc.<ctrl-space> and get a list of methods in that class. NEVER AGAIN TYPE A METHOD NAME. If there are a kagillion methods in your class, don't scroll over them, type: dlc.dLAM<ctrl-space> to get dlc.damnLongAnnoyingMethodNameStillHasToBeTypedEveryTime();
Never type a long method name again.
No long method names, no long class names, no long package names. Yet you get extremely readable methods, packages and classes. This is why java programmers tend to use these long names, we also try to remember that we are coding for the next guy and don't want him to have to run all over our code trying to figure out what:
g.m(); refers to -- forcing them to remember that in this class it means GreatClass.motion, but in the next class it means Grey.modifyColor -- that would be really cruel.
Java being statically typed places a LOT of power into the editor. It can do things that you can't even dream of doing with dynamically typed languages, and you should play to the strength of your language to be an effective programmer -- not try to fit each language into some style you learned from using another language.
Note that this works for static methods as well...
DLC<ctrl-space>.dLM<ctrl-space> would be replaced by a call to DamnLongClass.damnLongMethod(), and it would even include the parens for you in 9 keystrokes.
The Java language provides no aliasing mechanism.
However, you could ease your "pain" somewhat by some combination of the following:
For static methods, you can use static imports to avoid having the long class name.
You could declare your own convenience class with a short name and short method names, and implement the static methods to delegate to the real methods like:
public static void shortName(...) {
VeryLongClassName.veryLongMethodName(...);
}
For regular methods, you could implement a Wrapper class, or a subclass with more convenient method names. However, both have downsides from the maintenance and (depending on your JVM) performance perspectives.
In Java 8 and later, you could potentially take a method reference, assign it to a named variable, and use that to make your calls.
But lets step back:
If the real problem is that you are just fed up with typing long names, a solution is to use a modern IDE that supports completion of names as you type them. See #BillK's answer for example.
If the real problem is that you are fed up with the long names taking to much space, a solution is to use a wider screen / longer lines. Most monitors are big enough to display 120 character (or more) wide source code with no eye strain.
If neither of the above is the answer, consider just refactoring the offending code to use sensible (i.e. shorter) class and method names. Once again, a modern IDE can handle this kind of refactoring quickly and safely.
On the last point, I would consider that the overly long class names and method names are bad style. IMO, you are justified in taking the time to fix them yourself, or suggesting that they be fixed, especially if they constitute a "public" API for some library or module.
To those who would argue that long identifiers are good style because they convey more information, the counter argument is that they don't actually improve readability. But if you say that they do improve readability, then it follows that using aliases instead of the long identifiers would be reducing readability!
Actually there is a way to get 1/2 of what you're after.
Looking at your example:
LONGGGGGGGGGGGGGGGClass.longggggggggggggggggggggggggMethod();
It appears that longggggggggggggggggggggggggMethod is static. (If it weren't, you'd be prefixing it with a variable name, which you control the size of.)
You can use Java's static import feature to 'alias' or import the static methods of the LONGGGGGGGGGGGGGGGClass into your own class' namespace. Instead of the above code, you would only have to write this:
longggggggggggggggggggggggggMethod();
You can use inheritance or encapsulation to wrap the original class.
class g extends LONGCLASS
{
void a() { super.loooonnng(); }
}
or
class g
{
private LONGCLASS lc;
void a() { lc.loooonnng(); }
}
Not supported in Java.
There is an enhancement ticket (7166917) for adding aliases for imports which would be helpful. The idea is this :
import a.very.lng.pckage.* as shortpckg
import my.pckage.IsAVeryLongClassName as MyShort
public class Shorten
{
public static final Shorten m = new Shorten();
public int a(params)
{
return some_method_with_long_name(params);
}
public void b()
{
// whatever static code you want
}
}
In your main code then:
import static mypackage.Shorten.m;
...
int res = m.a(params);
m.b();
...
This way you effectively alias any static stuff you want, while avoiding warnings.
I only ran a simple test but I defined an inner class variable. I'm not an expert nor do I know the consequences of doing this but I obtained positive results.
package a.b;
public class Library {
public static String str;
}
Now write a class to access the static variables from Library
package a.b;
public class Access {
public class Short extends Library {}
Short.str;
}